feat(server): graceful shutdown on SIGINT/SIGTERM (#1)
This commit is contained in:
@@ -64,6 +64,34 @@ pub async fn run(config: Config) -> anyhow::Result<()> {
|
|||||||
serve(listener, state).await
|
serve(listener, state).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolves when the process receives SIGINT (Ctrl-C) or SIGTERM, so the server can
|
||||||
|
/// drain in-flight requests before exiting.
|
||||||
|
async fn shutdown_signal() {
|
||||||
|
let ctrl_c = async {
|
||||||
|
tokio::signal::ctrl_c()
|
||||||
|
.await
|
||||||
|
.expect("install Ctrl-C handler");
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
let terminate = async {
|
||||||
|
tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
|
||||||
|
.expect("install SIGTERM handler")
|
||||||
|
.recv()
|
||||||
|
.await;
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
let terminate = std::future::pending::<()>();
|
||||||
|
|
||||||
|
tokio::select! {
|
||||||
|
_ = ctrl_c => {},
|
||||||
|
_ = terminate => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
tracing::info!("shutdown signal received; draining");
|
||||||
|
}
|
||||||
|
|
||||||
/// Serve the API on an already-bound listener (used by `run` and tests).
|
/// Serve the API on an already-bound listener (used by `run` and tests).
|
||||||
pub async fn serve(listener: TcpListener, state: AppState) -> anyhow::Result<()> {
|
pub async fn serve(listener: TcpListener, state: AppState) -> anyhow::Result<()> {
|
||||||
let app = build_app(state);
|
let app = build_app(state);
|
||||||
@@ -72,6 +100,7 @@ pub async fn serve(listener: TcpListener, state: AppState) -> anyhow::Result<()>
|
|||||||
let app = app.merge(web_assets::routes());
|
let app = app.merge(web_assets::routes());
|
||||||
|
|
||||||
axum::serve(listener, app)
|
axum::serve(listener, app)
|
||||||
|
.with_graceful_shutdown(shutdown_signal())
|
||||||
.await
|
.await
|
||||||
.context("running the HTTP server")?;
|
.context("running the HTTP server")?;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user