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(());
22 }
23
24 pub async fn wait_shutdown(&self) {
26 let mut rx = self.tx.subscribe();
27 let _ = rx.recv().await;
28 }
29
30 pub fn subscribe(&self) -> broadcast::Receiver<()> {
32 self.tx.subscribe()
33 }
34}
35
36impl Default for ShutdownHandle {
37 fn default() -> Self {
38 Self::new()
39 }
40}
41
42pub async fn wait_for_signal() {
44 #[cfg(unix)]
45 {
46 use tokio::signal::unix::{signal, SignalKind};
47 let mut sigterm = signal(SignalKind::terminate()).expect("Failed to setup SIGTERM handler");
48 let mut sigint = signal(SignalKind::interrupt()).expect("Failed to setup SIGINT handler");
49
50 tokio::select! {
51 _ = sigterm.recv() => {
52 tracing::info!("Received SIGTERM, shutting down gracefully");
53 }
54 _ = sigint.recv() => {
55 tracing::info!("Received SIGINT, shutting down gracefully");
56 }
57 }
58 }
59
60 #[cfg(not(unix))]
61 {
62 tokio::signal::ctrl_c().await.expect("Failed to listen for Ctrl+C");
63 tracing::info!("Received Ctrl+C, shutting down gracefully");
64 }
65}