mecha10_runtime/
shutdown.rs1use tokio::sync::broadcast;
4
5#[derive(Clone)]
6pub struct ShutdownHandle {
7 tx: broadcast::Sender<()>,
8}
9
10impl ShutdownHandle {
11 pub fn new() -> Self {
13 let (tx, _) = broadcast::channel(1);
14 Self { tx }
15 }
16
17 pub fn shutdown(&self) {
19 let _ = self.tx.send(());
20 }
21
22 pub async fn wait_shutdown(&self) {
24 let mut rx = self.tx.subscribe();
25 let _ = rx.recv().await;
26 }
27
28 pub fn subscribe(&self) -> broadcast::Receiver<()> {
30 self.tx.subscribe()
31 }
32}
33
34impl Default for ShutdownHandle {
35 fn default() -> Self {
36 Self::new()
37 }
38}
39
40pub async fn wait_for_signal() {
42 #[cfg(unix)]
43 {
44 use tokio::signal::unix::{signal, SignalKind};
45 let mut sigterm = signal(SignalKind::terminate()).expect("Failed to setup SIGTERM handler");
46 let mut sigint = signal(SignalKind::interrupt()).expect("Failed to setup SIGINT handler");
47
48 tokio::select! {
49 _ = sigterm.recv() => {
50 tracing::info!("Received SIGTERM, shutting down gracefully");
51 }
52 _ = sigint.recv() => {
53 tracing::info!("Received SIGINT, shutting down gracefully");
54 }
55 }
56 }
57
58 #[cfg(not(unix))]
59 {
60 tokio::signal::ctrl_c().await.expect("Failed to listen for Ctrl+C");
61 tracing::info!("Received Ctrl+C, shutting down gracefully");
62 }
63}