use crate::Server;
use ayun_config::config;
use ayun_core::{
app,
traits::{ApplicationTrait, ErrorTrait, ServiceTrait},
BoxFuture, Error, Result,
};
use ayun_runtime::Runtime;
impl ServiceTrait for Server {
type Item = axum::Router;
fn new() -> Self {
Self::default()
}
fn register(mut self, item: Self::Item) -> Self {
self.inner = self.inner.merge(item);
self
}
fn init<A: ApplicationTrait>() -> Self {
(&A::with_routing() as &dyn std::any::Any)
.downcast_ref::<Self>()
.cloned()
.unwrap_or(Self::default())
}
fn run(self) -> Result<(), Error> {
let runtime = app().resolve::<Runtime>()?;
runtime
.block_on(serve(self.inner, Self::shutdown))
.map_err(Error::wrap)?;
Ok(())
}
}
async fn serve<F>(router: axum::Router, shutdown: F) -> Result<(), crate::Error>
where
F: Fn() -> BoxFuture<'static> + 'static + Send + Sync,
{
let config = config::<crate::config::Server>("server")?;
let listener = tokio::net::TcpListener::bind(&config.url).await?;
tracing::info!("server listening on {}", config.url);
axum::serve(listener, router)
.with_graceful_shutdown(shutdown())
.await?;
Ok(())
}