11use std:: {
22 collections:: VecDeque ,
3- sync:: atomic:: { AtomicBool , AtomicI8 } ,
3+ sync:: atomic:: { AtomicBool , AtomicI8 , Ordering } ,
44} ;
55
66use nix:: libc:: { self , sighandler_t} ;
77use parking_lot:: Mutex ;
88use tokio:: sync:: broadcast;
9+ use tracing:: { debug, warn} ;
910
1011use super :: lifecycle_event:: LifecycleEvent ;
1112
@@ -21,12 +22,14 @@ pub fn subscribe_runtime_to_signals() -> broadcast::Receiver<LifecycleEvent> {
2122 if let Some ( sender) = guard. as_ref ( ) {
2223 return sender. subscribe ( ) ;
2324 }
24- let ( sender, receiver) = broadcast:: channel ( 5 ) ;
25+ let ( sender, receiver) = broadcast:: channel ( 32 ) ;
2526 let sender_clone = sender. clone ( ) ;
2627 std:: thread:: spawn ( move || {
27- std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 50 ) ) ;
28+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 10 ) ) ;
2829 for event in PENDING_QUEUE . lock ( ) . drain ( ..) {
29- sender_clone. send ( event) . ok ( ) ;
30+ if let Err ( e) = sender_clone. send ( event) {
31+ eprintln ! ( "Warning: Failed to send pending lifecycle event {:?}" , e) ;
32+ }
3033 }
3134 } ) ;
3235
@@ -41,22 +44,36 @@ pub fn unsubscribe_runtime() {
4144
4245pub fn send_lifecycle_event ( event : LifecycleEvent ) {
4346 if let Some ( sender) = SIGNAL_HANDLER_CHANNEL . lock ( ) . as_ref ( ) {
44- sender. send ( event) . ok ( ) ;
47+ if let Err ( e) = sender. send ( event) {
48+ // Channel full or receivers dropped - this is a critical error for shutdown signals
49+ eprintln ! ( "Critical: Failed to send lifecycle event {:?}" , e) ;
50+ // For shutdown events, try to force exit if channel delivery fails
51+ if matches ! (
52+ e. 0 ,
53+ LifecycleEvent :: Shutdown | LifecycleEvent :: ForceShutdown
54+ ) {
55+ eprintln ! ( "Emergency shutdown due to signal delivery failure" ) ;
56+ std:: process:: exit ( 1 ) ;
57+ }
58+ }
4559 } else {
4660 PENDING_QUEUE . lock ( ) . push_back ( event) ;
4761 }
4862}
4963
5064fn receive_signal ( signum : i32 , _: sighandler_t ) {
51- SIGINT_COUNT . fetch_add ( -1 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
65+ debug ! ( "Received signal: {}" , signum) ;
66+ SIGINT_COUNT . fetch_add ( -1 , Ordering :: SeqCst ) ;
5267 let event = match signum {
5368 libc:: SIGTERM | libc:: SIGINT => {
54- SHUTDOWN_REQUESTED . store ( true , std:: sync:: atomic:: Ordering :: SeqCst ) ;
55- SIGINT_COUNT . fetch_add ( 2 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
56- if SIGINT_COUNT . load ( std:: sync:: atomic:: Ordering :: SeqCst ) < 2 {
69+ debug ! ( "Received shutdown signal (SIGTERM/SIGINT)" ) ;
70+ SHUTDOWN_REQUESTED . store ( true , Ordering :: SeqCst ) ;
71+ SIGINT_COUNT . fetch_add ( 2 , Ordering :: SeqCst ) ;
72+ if SIGINT_COUNT . load ( Ordering :: SeqCst ) < 2 {
73+ debug ! ( "First shutdown signal, requesting graceful shutdown" ) ;
5774 Some ( LifecycleEvent :: Shutdown )
5875 } else {
59- // Not messing about. Force shutdown.
76+ warn ! ( "Multiple shutdown signals received, forcing immediate shutdown" ) ;
6077 Some ( LifecycleEvent :: ForceShutdown )
6178 }
6279 }
@@ -70,13 +87,17 @@ fn receive_signal(signum: i32, _: sighandler_t) {
7087 } ;
7188
7289 if let Some ( event) = event {
90+ debug ! ( "Signal {} mapped to lifecycle event: {:?}" , signum, event) ;
7391 send_lifecycle_event ( event) ;
92+ } else {
93+ debug ! ( "Signal {} not mapped to any lifecycle event" , signum) ;
7494 }
7595}
7696
7797pub fn reset_signal_handlers ( ) -> bool {
78- SIGINT_COUNT . store ( 0 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
79- SHUTDOWN_REQUESTED . store ( false , std:: sync:: atomic:: Ordering :: SeqCst ) ;
98+ debug ! ( "Resetting signal handlers" ) ;
99+ SIGINT_COUNT . store ( 0 , Ordering :: SeqCst ) ;
100+ SHUTDOWN_REQUESTED . store ( false , Ordering :: SeqCst ) ;
80101
81102 unsafe {
82103 libc:: signal ( libc:: SIGTERM , receive_signal as usize ) ;
@@ -92,6 +113,7 @@ pub fn reset_signal_handlers() -> bool {
92113}
93114
94115pub fn clear_signal_handlers ( ) {
116+ debug ! ( "Clearing signal handlers" ) ;
95117 unsafe {
96118 libc:: signal ( libc:: SIGTERM , libc:: SIG_DFL ) ;
97119 libc:: signal ( libc:: SIGINT , libc:: SIG_DFL ) ;
0 commit comments