use tokio::sync::watch; use super::signals::Signals; pub struct Shutdown { rx: watch::Receiver, } pub fn install() -> Shutdown { let (tx, rx) = watch::channel(false); tokio::spawn(async move { let Some(mut signals) = Signals::new() else { tracing::error!("installing shutdown signal handlers failed"); std::future::pending::<()>().await; return; }; let first = signals.next().await; tracing::info!( signal = first, "shutdown signal received; draining in-flight work" ); let _ = tx.send(true); let second = signals.next().await; tracing::warn!( signal = second, "second shutdown signal received; exiting immediately" ); std::process::exit(1); }); Shutdown { rx } } impl Shutdown { pub async fn wait(mut self) { let _ = self.rx.wait_for(|requested| *requested).await; } }