Skip to main content

omni_dev/daemon/
lifecycle.rs

1//! Process-lifecycle wiring: translate OS termination signals into a graceful
2//! shutdown of the daemon's [`CancellationToken`].
3
4use tokio_util::sync::CancellationToken;
5
6/// Spawns a task that cancels `shutdown` when the process is asked to stop.
7///
8/// On Unix this listens for both `SIGTERM` (what `launchctl bootout` and
9/// service managers send) and `SIGINT` (Ctrl-C in a foreground `daemon run`).
10/// Elsewhere it listens for Ctrl-C only.
11pub fn install_signal_handlers(shutdown: CancellationToken) {
12    #[cfg(unix)]
13    {
14        use tokio::signal::unix::{signal, SignalKind};
15        tokio::spawn(async move {
16            let mut term = match signal(SignalKind::terminate()) {
17                Ok(s) => s,
18                Err(e) => {
19                    tracing::warn!("failed to install SIGTERM handler: {e}");
20                    return;
21                }
22            };
23            let mut interrupt = match signal(SignalKind::interrupt()) {
24                Ok(s) => s,
25                Err(e) => {
26                    tracing::warn!("failed to install SIGINT handler: {e}");
27                    return;
28                }
29            };
30            tokio::select! {
31                _ = term.recv() => tracing::info!("received SIGTERM; shutting down"),
32                _ = interrupt.recv() => tracing::info!("received SIGINT; shutting down"),
33            }
34            shutdown.cancel();
35        });
36    }
37    #[cfg(not(unix))]
38    {
39        tokio::spawn(async move {
40            if tokio::signal::ctrl_c().await.is_ok() {
41                tracing::info!("received Ctrl-C; shutting down");
42                shutdown.cancel();
43            }
44        });
45    }
46}