shuttle_actix_web/
lib.rs

1#![doc = include_str!("../README.md")]
2use std::net::SocketAddr;
3
4pub use actix_web;
5
6/// A wrapper type for a closure that returns an [actix_web::web::ServiceConfig] so we can implement
7/// [shuttle_runtime::Service] for it.
8#[derive(Clone)]
9pub struct ActixWebService<F>(pub F);
10
11#[shuttle_runtime::async_trait]
12impl<F> shuttle_runtime::Service for ActixWebService<F>
13where
14    F: FnOnce(&mut actix_web::web::ServiceConfig) + Send + Clone + 'static,
15{
16    async fn bind(mut self, addr: SocketAddr) -> Result<(), shuttle_runtime::Error> {
17        // Start a worker for each cpu, but no more than 4.
18        let worker_count = num_cpus::get().min(4);
19
20        let server =
21            actix_web::HttpServer::new(move || actix_web::App::new().configure(self.0.clone()))
22                .workers(worker_count)
23                .bind(addr)?
24                .run();
25
26        server.await.map_err(shuttle_runtime::CustomError::new)?;
27
28        Ok(())
29    }
30}
31
32impl<F> From<F> for ActixWebService<F>
33where
34    F: FnOnce(&mut actix_web::web::ServiceConfig) + Send + Clone + 'static,
35{
36    fn from(service_config: F) -> Self {
37        Self(service_config)
38    }
39}
40
41#[doc = include_str!("../README.md")]
42pub type ShuttleActixWeb<F> = Result<ActixWebService<F>, shuttle_runtime::Error>;