Graceful Tokio Shutdown with Notify
Signal shutdown with Tokio Notify, let each worker finish its current cycle, and join every task before the process exits.
Code
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::Notify;
use tokio::task::JoinSet;
use tokio::time::sleep;
#[tokio::main]
async fn main() {
let shutdown = Arc::new(Notify::new());
let mut tasks = JoinSet::new();
for worker in 0..3 {
let shutdown = Arc::clone(&shutdown);
tasks.spawn(async move {
loop {
tokio::select! {
_ = shutdown.notified() => {
println!("worker {worker} draining");
break;
}
_ = sleep(Duration::from_millis(25)) => {
println!("worker {worker} tick");
}
}
}
sleep(Duration::from_millis(20)).await;
println!("worker {worker} stopped");
});
}
sleep(Duration::from_millis(60)).await;
shutdown.notify_waiters();
while let Some(result) = tasks.join_next().await {
result.expect("worker panicked");
}
println!("shutdown complete");
}
Report a problem with this exampleOpens a pre-filled issue on GitHub.