use std::sync::{Arc, OnceLock};
use tracing::info;
#[cfg(unix)]
use tokio::signal::unix::{SignalKind, signal};
use tokio::sync::Notify;
static SHUTDOWN: OnceLock<Arc<Notify>> = OnceLock::new();
pub(crate) fn shutdown_notify() -> Arc<Notify> {
SHUTDOWN
.get_or_init(|| {
let notify = Arc::new(Notify::new());
let wake = Arc::clone(¬ify);
tokio::spawn(async move {
#[cfg(unix)]
{
let mut sigterm = signal(SignalKind::terminate())
.expect("register SIGTERM handler (required for PID 1 on Linux)");
let mut sigint =
signal(SignalKind::interrupt()).expect("register SIGINT handler");
tokio::select! {
_ = sigterm.recv() => info!("received SIGTERM"),
_ = sigint.recv() => info!("received SIGINT"),
}
}
#[cfg(not(unix))]
{
tokio::signal::ctrl_c()
.await
.expect("register Ctrl+C handler");
info!("received Ctrl+C");
}
wake.notify_waiters();
});
notify
})
.clone()
}
pub async fn wait_for_shutdown() {
shutdown_notify().notified().await;
}