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