I am buffering data which is flushed at intervals. There are cases where the application could (would) exit and that data should be flushed immediately regardless of the interval (i.e. exit(0/1/...)
in some other module etc.)
I have a combination of implementing Drop
and handling sending pending data when drop
is called. (trivial case where the objects are torn down elegantly)
impl Drop for AnalyticsSendQueue {
fn drop(&mut self) {
self.flush();
}
}
I've added a signal_hook to the best of my understanding:
if let Ok(mut s) = signal_hook::iterator::Signals::new(signal_hook::consts::TERM_SIGNALS) {
let bulk = Arc::clone(&self.bulk);
std::thread::spawn(move || {
for _ in s.forever() {
info!("got a signal");
let _ = bulk.lock().unwrap().send();
std::process::exit(1);
}
});
} else {
info!("error with signals");
}
Per my tests, this code isn't invoked when another module does exit(code)
For instance, I created a trivial background thread which will sleep for several seconds and then call exit
. The handlers aren't called (they are registered though, verified through logging and breakpoints):
std::thread::spawn(|| {
std::thread::sleep(Duration::from_secs(10));
std::process::exit(0); // handlers aren't invoked
});
Is there a way to resolve this?
EDIT!!!! My main concern is if "exit" gets called from some other module which I don't control