Search code examples
rustactix-web

How to start the actix-web server at a different lifecycle app point than at startup?


I'm writing an app in Rust that'll be a Windows system service and will additionally contain a simple small HTTP server using actix-web. However, I have a dilemma. In the actix documentation, it's mentioned to place #[actix_web::main] before the main() function:

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(hello)
            .service(echo)
            .route("/hey", web::get().to(manual_hello))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

However, in my app, the server won't be launched along with the application startup but only after initializing the service. Additionally, I'd like this service to be able to start and stop this server at any time. Therefore, I have a question: How do I run the actix-web server in my application? Should I add #[actix_web::main] even if the server isn't launched in main() but in another function? Or should I add it in a different place (e.g., the function that actually starts the server)?


Solution

  • What #[actix_web::main] does is set up an asynchronous runtime which then blocks on the body of the function. Doing so converts the async function into non-async. This does not have to be on main().

    Since the function will block while the server is running, you'll probably want to run it on its own thread. You may also want to acquire a ServerHandle before .await-ing the server since it allows you to pause and resume accepting connections.