alux_http_actix/
server.rs1use crate::ActixRoute;
2use actix_web::dev::ServerHandle;
3use actix_web::{App, HttpServer};
4use alux_http::{HttpServerAlg, HttpServerSetup};
5use tokio::task::JoinHandle;
6
7type ActixServerError = Box<dyn std::error::Error + Send + Sync>;
8
9const DRAIN: u64 = 5;
14
15#[derive(Debug, Default)]
17pub struct ActixServer;
18
19pub struct ActixOpen {
21 handle: ServerHandle,
22 task: JoinHandle<Result<(), ActixServerError>>,
23}
24
25impl Drop for ActixOpen {
26 fn drop(&mut self) {
27 let stopping = self.handle.stop(true);
30 drop(stopping);
31 self.task.abort();
32 }
33}
34
35impl HttpServerAlg for ActixServer {
36 type Program = ActixRoute;
37 type Open = ActixOpen;
38 type Error = ActixServerError;
39
40 async fn open(&mut self, setup: HttpServerSetup<Self::Program>) -> Result<Self::Open, Self::Error> {
41 let (bind, route) = setup.into_parts();
42 let configure = route.into_actix();
43 let listener = std::net::TcpListener::bind(bind.address())?;
46 let server = HttpServer::new(move || App::new().configure(configure.clone()))
47 .shutdown_timeout(DRAIN)
48 .disable_signals()
52 .listen(listener)?
53 .run();
54 let handle = server.handle();
55 let task = actix_web::rt::spawn(async move { server.await.map_err(Into::into) });
56
57 Ok(ActixOpen { handle, task })
58 }
59
60 async fn close(&mut self, open: &mut Self::Open) -> Result<(), Self::Error> {
61 open.handle.stop(true).await;
64 if !open.task.is_finished() {
65 let _ = (&mut open.task).await;
66 }
67
68 Ok(())
69 }
70
71 async fn end(&mut self, open: &mut Self::Open) -> Result<(), Self::Error> {
74 self.close(open).await
75 }
76}