use tokio::signal::unix::SignalKind;
use tokio::signal::unix::signal;
use tokio_util::sync::CancellationToken;
use tokio_util::task::TaskTracker;
pub struct SigDown {
task_tracker: TaskTracker,
cancellation_token: CancellationToken,
}
impl SigDown {
pub fn try_new() -> Result<Self, std::io::Error> {
let mut sigterm = signal(SignalKind::terminate())?;
let mut sigint = signal(SignalKind::interrupt())?;
let inner = CancellationToken::new();
let outer = inner.clone();
let task_tracker = TaskTracker::new();
task_tracker.spawn(async move {
tokio::select! {
_ = sigterm.recv() => {
inner.cancel();
},
_ = sigint.recv() => {
inner.cancel();
}
}
});
task_tracker.close();
Ok(Self {
task_tracker,
cancellation_token: outer,
})
}
pub fn cancellation_token(&self) -> CancellationToken {
self.cancellation_token.clone()
}
#[allow(dead_code)]
pub async fn recv(&self) {
self.cancellation_token.cancelled().await;
self.task_tracker.wait().await;
}
}