I actually ran into a problem when I worked with Sender
s that have no Receiver
. Consider the following example:
use tokio::sync::watch;
#[allow(unused_variables)]
fn main() {
let (sender, receiver) = watch::channel("initial");
//drop(receiver); // try to uncomment
sender.send("updated").ok();
let receiver2 = sender.subscribe();
let s = *receiver2.borrow();
assert_eq!(s, "updated"); // fails if `receiver` is dropped before `send`
}
Apparently the Sender
doesn't retain the last value if it was sent when there was no Receiver
. Is this intended?
The current behavior is kind-of documented here:
pub fn send(&self, value: T) -> Result<(), SendError>
Sends a new value via the channel, notifying all receivers.
This method fails if the channel has been closed, which happens when every receiver has been dropped.
It's not 100% clear what "fails" means in this context (i.e. returning Err(_)
or failing to update the value). Either way, I think it would be helpful if the sent value was retained for a future subscriber.
Due to the current behavior, I have to keep a "dummy" Receiver
in my code:
pub struct Receiver<T> {
watch: watch::Sender<Option<broadcast::Sender<Message<T>>>>,
_dummy: watch::Receiver<Option<broadcast::Sender<Message<T>>>>,
}
impl<T> Receiver<T>
where
T: Clone,
{
pub fn new() -> Self {
let (sender, receiver) = watch::channel(None);
Self {
watch: sender,
_dummy: receiver,
}
}
}
Update: Using Sender::send_replace
is a simpler solution than keeping a dummy receiver around.