I need help in understanding borrow() and borrow_and_update() both looking similar to me.
#[tokio::main]
async fn main() {
use tokio::sync::watch;
use tokio::time::{Duration, sleep};
let (tx, mut rx) = watch::channel("hello");
let mut rx2 = tx.subscribe();
tokio::spawn(async move {
loop {
println!("{}! ", *rx2.borrow_and_update());
if rx.changed().await.is_err() {
break;
}
}
});
sleep(Duration::from_millis(1000)).await;
tx.send("world").unwrap();
sleep(Duration::from_millis(1000)).await;
}
this is the example that I am using and I can't see any difference while using borrow()
and borrow_and_update()
.
I have read the docs which say borrow_and_seen()
will mark the value as seen while borrow
doesn't.
can anyone help me understanding these two by giving a suitable example.
There is a dedicated section in the documentation on when to use which:
borrow_and_update
versusborrow
If the receiver intends to await notifications from
changed
in a loop,Receiver::borrow_and_update()
should be preferred overReceiver::borrow()
. This avoids a potential race where a new value is sent betweenchanged
being ready and the value being read. (IfReceiver::borrow()
is used, the loop may run twice with the same value.)If the receiver is only interested in the current value, and does not intend to wait for changes, then
Receiver::borrow()
can be used. It may be more convenient to useborrow
since it's an&self
method—borrow_and_update
requires&mut self
.
Giving an example that consistently reproduces the loop running twice is hard because it relies on consistently hitting the race condition.