Skip to content

Commit

Permalink
sync: extend documentation for watch::Receiver::wait_for
Browse files Browse the repository at this point in the history
- The "Cancel safety" section was missing, as reported in #7021.
- Add the "Panics" section since technically the method can panic.
- Change the doctest to mimic the one for `changed` (also I find the
current version slightly more confusing than it should be).

Fixes: #7021
  • Loading branch information
cip999 committed Dec 15, 2024
1 parent 10e23d1 commit ff7025f
Showing 1 changed file with 23 additions and 17 deletions.
40 changes: 23 additions & 17 deletions tokio/src/sync/watch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -767,44 +767,50 @@ impl<T> Receiver<T> {
/// When this function returns, the value that was passed to the closure
/// when it returned `true` will be considered seen.
///
/// If the channel is closed, then `wait_for` will return a `RecvError`.
/// If the channel is closed, then `wait_for` will return a [`RecvError`].
/// Once this happens, no more messages can ever be sent on the channel.
/// When an error is returned, it is guaranteed that the closure has been
/// called on the last value, and that it returned `false` for that value.
/// (If the closure returned `true`, then the last value would have been
/// returned instead of the error.)
///
/// Like the `borrow` method, the returned borrow holds a read lock on the
/// Like the [`borrow`] method, the returned borrow holds a read lock on the
/// inner value. This means that long-lived borrows could cause the producer
/// half to block. It is recommended to keep the borrow as short-lived as
/// possible. See the documentation of `borrow` for more information on
/// this.
///
/// [`Receiver::changed()`]: crate::sync::watch::Receiver::changed
/// [`borrow`]: Receiver::borrow
/// [`RecvError`]: error::RecvError
///
/// # Cancel safety
///
/// This method is cancel safe. If dropped before completion, it is
/// guaranteed that the last seen value `val` (if any) satisfies
/// `f(val) == false`.
///
/// # Panics
///
/// If and only if the closure `f` panics. In that case, no resource owned
/// or shared by this [`Receiver`] will be poisoned.
///
/// # Examples
///
/// ```
/// use tokio::sync::watch;
/// use tokio::time::{sleep, Duration};
///
/// #[tokio::main]
///
/// async fn main() {
/// let (tx, _rx) = watch::channel("hello");
/// let (tx, mut rx) = watch::channel("hello");
///
/// tx.send("goodbye").unwrap();
/// tokio::spawn(async move {
/// sleep(Duration::from_micros(100)).await;
/// tx.send("goodbye").unwrap();
/// });
///
/// // here we subscribe to a second receiver
/// // now in case of using `changed` we would have
/// // to first check the current value and then wait
/// // for changes or else `changed` would hang.
/// let mut rx2 = tx.subscribe();
///
/// // in place of changed we have use `wait_for`
/// // which would automatically check the current value
/// // and wait for changes until the closure returns true.
/// assert!(rx2.wait_for(|val| *val == "goodbye").await.is_ok());
/// assert_eq!(*rx2.borrow(), "goodbye");
/// assert!(rx.wait_for(|val| *val == "goodbye").await.is_ok());
/// assert_eq!(*rx.borrow(), "goodbye");
/// }
/// ```
pub async fn wait_for(
Expand Down

0 comments on commit ff7025f

Please sign in to comment.