Async "shutdown signal" implementation

⚓ Rust    📅 2025-11-18    👤 surdeus    👁️ 7      

surdeus

I'm implementing a type for telling multiple async tasks to shut down. Requirements:

  • Function that returns a (ShutdownSender, ShutdownReceiver) pair
  • ShutdownSender doesn't need any methods. When you drop it, that signals that it's time for shutdown.
  • ShutdownReceiver is Clone so multiple tasks can wait for the same shutdown signal.
  • ShutdownReceiver has a method async fn recv(&self) that waits for the signal to be sent.
  • recv is cancel-safe.
  • After recv is successfully awaited the first time, it's OK to call it again; it just returns right away.

I've implemented it using a Tokio watch channel, and that works fine, but I'm not using most of a watch channel's features. Also, my implementation of recv has to clone the receiver (to satisfy the non-mut part of requirement 4 and I think also requirement 6), which bumps a refcount. That seems unnecessary. (Admittedly, the perf probably isn't worth worrying about, even though we do call recv() in lots of select! loops.)

Is there a better primitive to use here? Is there a crate that does exactly what I want?

4 posts - 3 participants

Read full topic

🏷️ Rust_feed