How to run the service in tokio::spawn

My requirement is to write a microservice framework called TestApp, inject multiple http and grpc services through add_server, run the run method, and then start the entire application (including http and grpc services, the difference is that they are run in tasks).

In the connection, view the problem

#[tokio::main]
async fn main() {
    TestApp::new()
        .add_server(TestHttp::new())
        .add_server(TestGrpc::new())
        .run()
        .await;
}

struct TestApp {
    servers: Vec<Box<dyn TestServer>>,
}

impl TestApp {
    fn new() -> Self {
        Self {
            servers: Vec::new(),
        }
    }
    fn add_server<T>(&mut self, srv: T) -> &mut Self
    where
        T: TestServer + 'static,
    {
        self.servers.push(Box::new(srv));
        self
    }
    async fn run(&self) {
        for srv in self.servers {
            tokio::spawn(async move {
                srv.start();
            });
        }

        tokio::signal::ctrl_c().await.expect("ctrl+c");
        self.stop();
    }
    fn stop(&self) {
        println!("----stop-app--");
    }
}



// ------server--------
trait TestServer {
    fn start(&self);
}

struct TestHttp;
impl TestHttp {
    fn new() -> Self {
        Self
    }
}
impl TestServer for TestHttp {
    fn start(&self) {
        println!("---http---")
    }
}

struct TestGrpc;
impl TestGrpc {
    fn new() -> Self {
        Self
    }
}
impl TestServer for TestGrpc {
    fn start(&self) {
        println!("---grpc---")
    }
}

Write an actual question. We can't read your mind. There's no question, compiler error, or runtime error. How can you expect us to help if you don't post a coherent question?

1 Like

The main post has been updated to see if it clarifies the problem

Please say more here, in particular describe "the problem". If this code doesn't compile, perhaps put it in the playground so we can see the compiler error, or post the full error here. If it doesn't behave as expected or is incomplete, say more about that.

1 Like

Please check the problem in Rust Playground. The error displayed on the Playground is the same as my local error. Maybe it is just learned, and I know there is a problem, but I don't know how to deal with it

Right now there is no output from the playground. Earlier I ran it and there were no errors.

You haven't properly shared your playground. If someone opens that link they will see the playground as they have last left it, not how you see it. You need to click the Share icon on the top left to actually the a shareable link.


That said this now compiles. It adds a Send and Sync requirement on the servers to allow sending them to a different thread. Moreover it replaces the Box with Arc because in run you only get shared access to the servers, but you can't spawn a tokio task by giving it a non-'static reference, thus an Arc is used to guarantee that the servers remain alive while the task is running.

Finally, I suggest you to make the start method async and not perform blocking operations inside it. As is if start does any blocking operation the tokio runtime may not run other tasks, such as those of the other servers, and that will break your application. See also tokio - Rust

2 Likes

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.