#[cfg(unix)]
pub fn shutdown_signal() -> impl std::future::Future<Output = ()> + Send + 'static {
use tokio::signal::unix::{SignalKind, signal};
let sigterm = signal(SignalKind::terminate());
let sigint = signal(SignalKind::interrupt());
async move {
let _signal_name = match (sigterm, sigint) {
(Ok(mut sigterm), Ok(mut sigint)) => {
tokio::select! {
_ = sigint.recv() => "SIGINT",
_ = sigterm.recv() => "SIGTERM",
}
}
(Ok(mut sigterm), Err(_sigint_error)) => {
#[cfg(feature = "tracing")]
tracing::warn!(
error = %_sigint_error,
"could not install SIGINT handler; only SIGTERM will trigger shutdown"
);
let _ = sigterm.recv().await;
"SIGTERM"
}
(Err(_sigterm_error), Ok(mut sigint)) => {
#[cfg(feature = "tracing")]
tracing::warn!(
error = %_sigterm_error,
"could not install SIGTERM handler; only SIGINT will trigger shutdown"
);
let _ = sigint.recv().await;
"SIGINT"
}
(Err(_sigterm_error), Err(_sigint_error)) => {
#[cfg(feature = "tracing")]
tracing::warn!(
sigterm_error = %_sigterm_error,
sigint_error = %_sigint_error,
"could not install SIGTERM or SIGINT handler"
);
std::future::pending::<&'static str>().await
}
};
#[cfg(feature = "tracing")]
tracing::info!(signal = _signal_name, "shutdown signal received");
}
}
#[cfg(not(unix))]
pub async fn shutdown_signal() {
let _ = tokio::signal::ctrl_c().await;
#[cfg(feature = "tracing")]
tracing::info!(signal = "SIGINT", "shutdown signal received");
}