mecha10-runtime 0.8.0

Runtime supervisor for Mecha10 nodes - launching, monitoring, and lifecycle management
Documentation
//! Graceful shutdown handling

use tokio::sync::broadcast;

#[derive(Clone)]
pub struct ShutdownHandle {
    tx: broadcast::Sender<()>,
}

impl ShutdownHandle {
    /// Create a new shutdown handle
    pub fn new() -> Self {
        let (tx, _) = broadcast::channel(1);
        Self { tx }
    }

    /// Trigger shutdown
    pub fn shutdown(&self) {
        let _ = self.tx.send(());
    }

    /// Wait for shutdown signal
    pub async fn wait_shutdown(&self) {
        let mut rx = self.tx.subscribe();
        let _ = rx.recv().await;
    }

    /// Subscribe to shutdown signals
    pub fn subscribe(&self) -> broadcast::Receiver<()> {
        self.tx.subscribe()
    }
}

impl Default for ShutdownHandle {
    fn default() -> Self {
        Self::new()
    }
}

/// Wait for Ctrl+C signal
pub async fn wait_for_signal() {
    #[cfg(unix)]
    {
        use tokio::signal::unix::{signal, SignalKind};
        let mut sigterm = signal(SignalKind::terminate()).expect("Failed to setup SIGTERM handler");
        let mut sigint = signal(SignalKind::interrupt()).expect("Failed to setup SIGINT handler");

        tokio::select! {
            _ = sigterm.recv() => {
                tracing::info!("Received SIGTERM, shutting down gracefully");
            }
            _ = sigint.recv() => {
                tracing::info!("Received SIGINT, shutting down gracefully");
            }
        }
    }

    #[cfg(not(unix))]
    {
        tokio::signal::ctrl_c().await.expect("Failed to listen for Ctrl+C");
        tracing::info!("Received Ctrl+C, shutting down gracefully");
    }
}