use std::future::Future;
use crate::application::Result;
use crate::application::shutdown;
use crate::application::startup;
use crate::application::ty::Application;
impl<S> Application<S>
where
S: Clone + Send + Sync + 'static,
{
pub async fn serve_with_lifecycle<L, F, Sh>(
self,
listener: L,
state_fn: F,
shutdown_signal: Sh,
) -> Result<()>
where
L: crate::axum::serve::Listener,
L::Addr: std::fmt::Debug,
F: Fn(&crate::application::Resources) -> S + Send + Sync + 'static,
Sh: Future<Output = ()> + Send + 'static,
{
let (started, resolved_app) = startup::startup(self).await?;
let state = state_fn(&started.resources);
let routes = resolved_app.routes.with_state(state);
let app = Application {
routes,
proxy: resolved_app.proxy,
bind_address: resolved_app.bind_address,
port: resolved_app.port,
#[cfg(feature = "inertia")]
inertia_config: resolved_app.inertia_config,
#[cfg(feature = "inertia")]
page_contracts: resolved_app.page_contracts,
#[cfg(feature = "pages")]
pages: resolved_app.pages,
#[cfg(feature = "pages")]
maintenance_guard: resolved_app.maintenance_guard,
#[cfg(feature = "db")]
database: None,
#[cfg(feature = "cache")]
cache_config: None,
#[cfg(feature = "storage")]
storage_config: None,
#[cfg(feature = "mail")]
mail_config: None,
#[cfg(feature = "jobs")]
jobs_registry: None,
#[cfg(feature = "jobs")]
worker_config: None,
#[cfg(feature = "dx")]
error_mapping: resolved_app.error_mapping,
#[cfg(feature = "dev-proxy")]
dev_proxy_endpoint: resolved_app.dev_proxy_endpoint,
};
let serve_result = app.serve_with_shutdown(listener, shutdown_signal).await;
let shutdown_result = shutdown::shutdown(started).await;
match serve_result {
Ok(()) => shutdown_result,
Err(serve_err) => {
if let Err(ref shutdown_err) = shutdown_result {
eprintln!("warning: shutdown also failed after serve error: {shutdown_err}");
}
Err(serve_err)
}
}
}
}