monitor/src/options/signals.rs

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())
}
}