Skip to content

Instantly share code, notes, and snippets.

@DoumanAsh
Created February 14, 2024 10:58
Show Gist options
  • Save DoumanAsh/258cb344b0cf1c76e6319beecbdf50bf to your computer and use it in GitHub Desktop.
Save DoumanAsh/258cb344b0cf1c76e6319beecbdf50bf to your computer and use it in GitHub Desktop.
tokio's signal handler to await termination
use core::future::Future;
use core::pin::Pin;
use core::task;
use std::io;
///Future that resolves when program is requested to terminate
#[must_use = "Future does nothing without polling"]
pub struct Termination {
#[cfg(unix)]
term: tokio::signal::unix::Signal,
#[cfg(unix)]
interrupt: tokio::signal::unix::Signal,
#[cfg(windows)]
interrupt: tokio::signal::windows::CtrlC,
}
impl Termination {
#[inline]
///Creates termination future, returning error if underlying signal handler cannot be created
pub fn new() -> io::Result<Self> {
Ok(Self {
#[cfg(unix)]
term: tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())?,
#[cfg(unix)]
interrupt: tokio::signal::unix::signal(tokio::signal::unix::SignalKind::interrupt())?,
#[cfg(windows)]
interrupt: tokio::signal::windows::ctrl_c()?,
})
}
}
impl Future for Termination {
type Output = ();
fn poll(self: Pin<&mut Self>, ctx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
let this = self.get_mut();
#[cfg(unix)]
{
if let task::Poll::Ready(Some(())) = this.term.poll_recv(ctx) {
tracing::info!("Termination");
return task::Poll::Ready(());
}
}
if let task::Poll::Ready(Some(())) = this.interrupt.poll_recv(ctx) {
tracing::info!("Interrupt");
return task::Poll::Ready(());
}
task::Poll::Pending
}
}
#[tracing::instrument]
///Await for process to be terminated or interrupted.
///
///If signal handler cannot be installed, wait forever
pub async fn await_termination() {
match Termination::new() {
Ok(termination) => {
termination.await;
}
Err(error) => {
tracing::error!(%error, "Cannot monitor for termination");
core::future::pending().await
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment