use crate::prelude::*;
use std::process::exit;
use std::sync::atomic::{AtomicBool, Ordering};
use tokio::signal::ctrl_c;
use tokio::spawn;
pub struct Shutdown {
requested: AtomicBool,
}
#[injectable]
impl Shutdown {
#[must_use]
pub fn new() -> Self {
Self {
requested: AtomicBool::new(false),
}
}
pub fn is_requested(&self) -> bool {
self.requested.load(Ordering::Relaxed)
}
fn request(&self) {
self.requested.store(true, Ordering::Relaxed);
}
pub fn listen(self: &Ref<Self>) {
let shutdown = self.clone();
spawn(async move {
ctrl_c().await.ok();
shutdown.request();
info!(
"{} graceful shutdown.\nFinishing current item.\nPress Ctrl+C again to exit immediately.",
"Triggered".bold()
);
ctrl_c().await.ok();
info!("{} immediate shutdown", "Triggered".bold());
exit(1);
});
}
}