mod signals;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use tokio::sync::Notify;
#[derive(Clone)]
pub struct GracefulShutdown {
pub(super) triggered: Arc<AtomicBool>,
notify: Arc<Notify>,
}
impl GracefulShutdown {
pub fn new() -> Self {
Self {
triggered: Arc::new(AtomicBool::new(false)),
notify: Arc::new(Notify::new()),
}
}
pub fn is_triggered(&self) -> bool {
self.triggered.load(Ordering::Acquire)
}
pub fn trigger(&self) {
self.triggered.store(true, Ordering::Release);
self.notify.notify_waiters();
}
pub async fn wait_for_shutdown(&self) {
self.notify.notified().await;
}
pub fn spawn_signal_handler(self) {
signals::spawn(self);
}
}
impl Default for GracefulShutdown {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::GracefulShutdown;
#[test]
fn trigger_sets_triggered_flag() {
let g = GracefulShutdown::new();
assert!(!g.is_triggered());
g.trigger();
assert!(g.is_triggered());
}
}