torrust_index/web/api/server/
signals.rs1use std::net::SocketAddr;
2use std::time::Duration;
3
4use derive_more::Display;
5use tokio::time::sleep;
6use tracing::info;
7
8#[derive(Copy, Clone, Debug, Display)]
11pub struct Started {
12 pub socket_addr: SocketAddr,
13}
14
15#[derive(Copy, Clone, Debug, Display)]
18pub enum Halted {
19 Normal,
20}
21
22pub async fn graceful_shutdown(handle: axum_server::Handle, rx_halt: tokio::sync::oneshot::Receiver<Halted>, message: String) {
23 shutdown_signal_with_message(rx_halt, message).await;
24
25 info!("Sending graceful shutdown signal");
26 handle.graceful_shutdown(Some(Duration::from_secs(90)));
27
28 println!("!! shuting down in 90 seconds !!");
29
30 loop {
31 sleep(Duration::from_secs(1)).await;
32
33 info!("remaining alive connections: {}", handle.connection_count());
34 }
35}
36
37pub async fn shutdown_signal_with_message(rx_halt: tokio::sync::oneshot::Receiver<Halted>, message: String) {
39 shutdown_signal(rx_halt).await;
40
41 info!("{message}");
42}
43
44pub async fn shutdown_signal(rx_halt: tokio::sync::oneshot::Receiver<Halted>) {
50 let halt = async {
51 match rx_halt.await {
52 Ok(signal) => signal,
53 Err(err) => panic!("Failed to install stop signal: {err}"),
54 }
55 };
56
57 tokio::select! {
58 signal = halt => { info!("Halt signal processed: {}", signal) },
59 () = global_shutdown_signal() => { info!("Global shutdown signal processed") }
60 }
61}
62
63pub async fn global_shutdown_signal() {
69 let ctrl_c = async {
70 tokio::signal::ctrl_c().await.expect("failed to install Ctrl+C handler");
71 };
72
73 #[cfg(unix)]
74 let terminate = async {
75 tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
76 .expect("failed to install signal handler")
77 .recv()
78 .await;
79 };
80
81 #[cfg(not(unix))]
82 let terminate = std::future::pending::<()>();
83
84 tokio::select! {
85 () = ctrl_c => {},
86 () = terminate => {}
87 }
88}