use crate::api::ApiHandler; use crate::config::Config; use crate::state::StateManager; use anyhow::Result; use hyper::server::conn::Http; use hyper::service::service_fn; use std::net::SocketAddr; use std::sync::Arc; use tokio::net::TcpListener; use tracing::error; pub struct Server { _config: Config, api_handler: Arc, } impl Server { pub async fn new(config: Config) -> Result { let state_manager = Arc::new(StateManager::new()); let api_handler = Arc::new(ApiHandler::new(config.clone(), state_manager).await?); Ok(Self { _config: config, api_handler, }) } pub async fn serve(&self, addr: SocketAddr) -> Result<()> { let listener = TcpListener::bind(addr).await?; loop { let (stream, peer_addr) = match listener.accept().await { Ok(conn) => conn, Err(e) => { error!("Failed to accept connection: {}", e); continue; } }; let handler = self.api_handler.clone(); tokio::spawn(async move { let service = service_fn(move |req| { let handler = handler.clone(); async move { handler.handle_request(req).await .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", e))) } }); if let Err(e) = Http::new() .serve_connection(stream, service) .with_upgrades() .await { error!("Error serving connection from {}: {}", peer_addr, e); } }); } } }