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
