//! Unix signals use super::*; use tokio::{ signal::unix::{ self, SignalKind, }, }; pub async fn handle(mut state: State) { let mut usr1 = unix::signal(SignalKind::user_defined1()).expect("Failed to hook SIGUSR1"); let mut usr2 = unix::signal(SignalKind::user_defined2()).expect("Failed to hook SIGUSR2"); let mut quit = unix::signal(SignalKind::quit()).expect("Failed to hook SIGQUIT"); let mut io = unix::signal(SignalKind::io()).expect("Failed to hook IO"); trace!("Setup oke. Waiting on init"); if state.on_init().await.is_ok() { debug!("Begin signal handler"); loop { tokio::select! { _ = state.on_shutdown() => { break; } _ = usr1.recv() => { info!("Got SIGUSR1. Causing chain write."); state.push_now(); }, _ = usr2.recv() => { info!("Got SIGUSR2. Loading chain immediately."); match save::load(&state.config().file).await { Ok(new) => { { let mut chain = state.chain_ref().write().await; *chain = new; } trace!("Replaced with read chain"); }, Err(e) => { error!("Failed to load chain from file, keeping current: {}", e); }, } }, _ = io.recv() => { info!("Got SIGIO. Saving chain immediately."); if let Err(e) = save::save_now(&state).await { error!("Failed to save chain: {}", e); } else{ trace!("Saved chain okay"); } }, _ = quit.recv() => { warn!("Got SIGQUIT. Saving chain then aborting."); if let Err(e) = save::save_now(&state).await { error!("Failed to save chain: {}", e); } else{ trace!("Saved chain okay."); } error!("Aborting"); std::process::abort() }, } } } else { debug!("Shutdown called before init()"); } trace!("Exiting"); }