-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sync: improve docs for watch channels #5954
Conversation
I found the watch docs as written to be somewhat confusing. * It wasn't clear to me whether values are marked seen or not at creation/subscribe time. * The example also confused me a bit, suggesting a while loop when a do-while loop is generally more correct. * I noticed a potential race with `borrow` that is no longer an issue with `borrow_and_update`. Update the documentation to try and make it clearer.
tokio/src/sync/watch.rs
Outdated
//! use [`Receiver::borrow_and_update()`]. | ||
//! | ||
//! To access the latest value but **not** mark it as seen, use | ||
//! [`Receiver::borrow()`]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might want to mention here that if the value has already been seen its state doesn't change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks reasonable to me.
tokio/src/sync/watch.rs
Outdated
//! * On completion, the [`changed`] method marks the new value as *seen*. If | ||
//! [`Receiver::changed()`] is called again, it will not be ready unless a | ||
//! subsequent value is sent. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence is a bit confusing. Can we rephrase "not be ready" to "not return immediately" or similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only minor nits. Overall looks good!
tokio/src/sync/watch.rs
Outdated
//! * The [`changed`] method returns `Ok(())` on receiving a new value, or | ||
//! `Err(_)` if the [`Sender`] has been closed. | ||
//! * On completion, the [`changed`] method marks the new value as *seen*. If | ||
//! [`Receiver::changed()`] is called again, it will not return immediately | ||
//! unless a subsequent value is sent. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps it would make sense to add this point somewhere here?
- If the latest value is unseen when calling
changed
, thenchanged
will return immediately. If the latest message is seen, then it will sleep until a new message is sent.
I don't think the current way its written make this sufficiently clear.
Then the second point can also be simplified to this:
- On completion, the
changed
method marks the new value as seen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to @Darksonn's comment. Also, perhaps some of this documentation should also be copied into the Receiver::changed()
docs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this a lot. Updated with this + also a mention that the sender can be dropped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this looks great, thanks for working on it! I commented on some very minor nitpicks and edits, let me know what you think!
tokio/src/sync/watch.rs
Outdated
//! * The [`changed`] method returns `Ok(())` on receiving a new value, or | ||
//! `Err(_)` if the [`Sender`] has been closed. | ||
//! * On completion, the [`changed`] method marks the new value as *seen*. If | ||
//! [`Receiver::changed()`] is called again, it will not return immediately | ||
//! unless a subsequent value is sent. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to @Darksonn's comment. Also, perhaps some of this documentation should also be copied into the Receiver::changed()
docs?
tokio/src/sync/watch.rs
Outdated
//! To access the **latest** value stored in the channel and mark it as *seen*, | ||
//! use [`Receiver::borrow_and_update()`]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you think it's worth explicitly stating something like "borrow_and_update()
should be preferred if the receiver intends to await notifications from changed()
"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kinda added that to the examples section but maybe I should move it up to this section.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved it into a new section titled "borrow_and_update
versus borrow
". Hopefully that works.
//! [`Receiver::borrow()`]. (If the value has already been marked *seen*, | ||
//! [`Receiver::borrow()`] is equivalent to [`Receiver::borrow_and_update()`].) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you think it's worth explicitly stating something like "borrow_and_update()
should be preferred if the receiver intends to await notifications from changed()
, but it is not required if the receiver is just looking at the current value of the shared state without waiting for changes"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added this to the new section, and also mentioned why borrow
can be more convenient (it's &self
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you think we should maybe add a
//! [`Receiver::borrow()`]. (If the value has already been marked *seen*, | |
//! [`Receiver::borrow()`] is equivalent to [`Receiver::borrow_and_update()`].) | |
//! [`Receiver::borrow()`]. (If the value has already been marked *seen*, | |
//! [`Receiver::borrow()`] is equivalent to [`Receiver::borrow_and_update()`].) | |
//! | |
//! See [here](#borrow-and-update-versus-borrow) for more information on when | |
//! to use these methods. |
or something?
tokio/src/sync/watch.rs
Outdated
//! method is ready when a new, *unseen* value is sent via the [`Sender`] half. | ||
//! | ||
//! * The [`changed`] method returns `Ok(())` on receiving a new value, or | ||
//! `Err(_)` if the [`Sender`] has been closed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very tiny nit, not actually important: this returns a public named error type, so we could actually reference it:
//! `Err(_)` if the [`Sender`] has been closed. | |
//! `Err(`[`errors::RecvError`]`)` if the [`Sender`] has been closed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Done, thanks for the comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks great to me overall! i'd like to see links back to the section on "borrow_and_update
versus borrow
" in the method docs for those methods --- mind adding that?
//! ## `borrow_and_update` versus `borrow` | ||
//! | ||
//! If the receiver intends to await notifications from [`changed`] in a loop, | ||
//! [`Receiver::borrow_and_update()`] should be preferred over | ||
//! [`Receiver::borrow()`]. This avoids a potential race where a new value is | ||
//! sent between [`changed`] being ready and the value being read. (If | ||
//! [`Receiver::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 use [`borrow`](Receiver::borrow) since it's an `&self` | ||
//! method---[`borrow_and_update`](Receiver::borrow_and_update) requires `&mut | ||
//! self`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is fantastic --- but i think the doc comments for borrow
and borrow_and_update
probably ought to link back to this section. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
//! [`Receiver::borrow()`]. (If the value has already been marked *seen*, | ||
//! [`Receiver::borrow()`] is equivalent to [`Receiver::borrow_and_update()`].) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you think we should maybe add a
//! [`Receiver::borrow()`]. (If the value has already been marked *seen*, | |
//! [`Receiver::borrow()`] is equivalent to [`Receiver::borrow_and_update()`].) | |
//! [`Receiver::borrow()`]. (If the value has already been marked *seen*, | |
//! [`Receiver::borrow()`] is equivalent to [`Receiver::borrow_and_update()`].) | |
//! | |
//! See [here](#borrow-and-update-versus-borrow) for more information on when | |
//! to use these methods. |
or something?
Added links. I think this is ready to go now. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks great to me!
Motivation
I found the watch docs as written to be somewhat confusing.
borrow
that is no longer an issue withborrow_and_update
.Solution
Update the documentation for the watch module to try and make all this clearer.