How to start another task along with tonic server

Hello, I'm a newbie of rust. I'm using tonic library to start a grpc server (the grpc server receives requests and then push the request data to a queue) and before starting the server, I want to start another task to consume the queue,it is an infinite loop.

use controller::controller_server::ControllerServer;
use std::sync::Arc;
use tokio::sync::Mutex;
use tonic::transport::Server;

pub mod codec;
pub mod controller;
pub mod error;
pub mod executor;
pub mod mq;
pub mod translate;
pub mod utils;

mod controller_proto {
    include!("controller.rs");

    pub(crate) const FILE_DESCRIPTOR_SET: &[u8] =
        tonic::include_file_descriptor_set!("controller_descriptor");
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    env_logger::init();

    let cfg = executor::ExecutorConfig::from_env()?;

    let addr = format!("0.0.0.0:{}", cfg.port);
    let mut executor = executor::Executor::from_config(cfg)?;

    let reflection_service = tonic_reflection::server::Builder::configure()
        .register_encoded_file_descriptor_set(controller_proto::FILE_DESCRIPTOR_SET)
        .build()
        .unwrap();

    tokio::spawn(executor.start());

    log::info!("executor listen on: {}", addr);
    Server::builder()
        .add_service(ControllerServer::new(executor))
        .add_service(reflection_service)
        .serve(addr.parse()?)
        .await?;

    Ok(())
}                                                                                                                               

But the code did not compiled, the compiler says: "cannot move out of executor because it is borrowed"
what should I do ?

what is your Executor definition? you code doesn't provide any information. also, what is the ControllerServer definition?

It looks like you are trying to share executor by using it in two places at once:

tokio::spawn(executor.start());
.add_service(ControllerServer::new(executor))

This can never work. Both of these must necessarily have ownership of executor to work, but Rust enforces that each variable has only one owner.

You haven't included the source code for executor, but based on how you're using it, it looks like your executor is an actor. You can read how to correctly implement actors in Rust in this article:

Specifically, it looks like your ControllerServer should be modified to be an actor handle.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.