87 lines
2.3 KiB
Rust
87 lines
2.3 KiB
Rust
use crate::options::structs::CustomError;
|
|
use std::sync::Arc;
|
|
use tokio::io;
|
|
use tokio::sync::mpsc;
|
|
use tokio::{
|
|
select,
|
|
signal::unix::{signal, Signal, SignalKind},
|
|
};
|
|
|
|
type SendersVec = Arc<Vec<Arc<mpsc::Sender<u8>>>>;
|
|
|
|
pub async fn set_valid_destructor(senders: SendersVec) -> Result<(), CustomError> {
|
|
let (mut int, mut term, mut stop) = (
|
|
Sig::new(Signals::Sigint, senders.clone()),
|
|
Sig::new(Signals::Sigterm, senders.clone()),
|
|
Sig::new(Signals::Sigstop, senders.clone()),
|
|
);
|
|
|
|
select! {
|
|
_ = int.post_processing() => {log::info!("Initializing interruption...")},
|
|
_ = term.post_processing() => {log::info!("Initializing termination...")},
|
|
_ = stop.post_processing() => {log::info!("Initializing freezing...")},
|
|
}
|
|
Ok(())
|
|
}
|
|
enum Signals {
|
|
Sigint,
|
|
Sigterm,
|
|
Sigstop,
|
|
}
|
|
struct Sig {
|
|
signal: Signal,
|
|
sig_type: Signals,
|
|
senders: SendersVec,
|
|
}
|
|
impl Sig {
|
|
fn new(signal_type: Signals, sends: SendersVec) -> Self {
|
|
Sig {
|
|
signal: signal_type.get_signal().unwrap(),
|
|
sig_type: signal_type,
|
|
senders: sends,
|
|
}
|
|
}
|
|
}
|
|
impl std::fmt::Display for Signals {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
match self {
|
|
Signals::Sigint => write!(f, "SIGINT"),
|
|
Signals::Sigterm => write!(f, "SIGTERM"),
|
|
Signals::Sigstop => write!(f, "SIGSTOP"),
|
|
}
|
|
}
|
|
}
|
|
impl Signals {
|
|
fn get_signal(&self) -> io::Result<Signal> {
|
|
match self {
|
|
Signals::Sigint => signal(SignalKind::interrupt()),
|
|
Signals::Sigterm => signal(SignalKind::terminate()),
|
|
Signals::Sigstop => signal(SignalKind::quit()),
|
|
}
|
|
}
|
|
}
|
|
trait SigPostProcessing {
|
|
async fn post_processing(&mut self) -> io::Result<()>;
|
|
}
|
|
impl SigPostProcessing for Sig {
|
|
async fn post_processing(&mut self) -> io::Result<()> {
|
|
// manipulations ...
|
|
if self.signal.recv().await.is_some() {
|
|
log::info!("Got {} signal", self.sig_type);
|
|
for prc in self.senders.clone().iter() {
|
|
let _ = prc.send(111).await;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod signals_unittest {
|
|
use super::*;
|
|
#[tokio::test]
|
|
async fn get_signal_check() {
|
|
assert!(Signals::Sigint.get_signal().is_ok())
|
|
}
|
|
}
|