-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
sync: implement 'Clone' for watch::Sender #5936
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
Conversation
pub fn has_changed(&self) -> Result<bool, error::RecvError> { | ||
// Load the version from the state | ||
let state = self.shared.state.load(); | ||
if state.is_closed() { | ||
if self.shared.is_sender_closed() { | ||
// The sender has dropped. | ||
return Err(error::RecvError(())); | ||
} | ||
let new_version = state.version(); | ||
|
||
// Load the version from the state | ||
let new_version = self.shared.version(); | ||
Ok(self.version != new_version) | ||
} |
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 method seems to not match maybe_changed
because the order of checking whether it's closed and the version has changed is different. The behavior in other places is that it will give one last true
when all the Senders are gone before returning an error, but here it gives an error even when there's an unobserved change.
Maybe I should change it to match behavior?
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 believe the inconsistency does exists, but
- the current version do exactly as the comment say,
Returns an error if the channel has been closed.
maybe_changed
is not a pub method.
The impact of inconsistency may be not particularly large.
But the maybe_changed
method does affect the behavior of pub method changed
. The comments of changed
should be modified to
This method returns an error if there is no new value in the channel has not yet been marked seen and all [`Sender`]s are dropped.
from
This method returns an error if and only if the [`Sender`] is dropped.
// Load the version from the state | ||
let state = self.shared.state.load(); | ||
if state.is_closed() { | ||
if self.shared.is_sender_closed() { | ||
// The sender has dropped. | ||
return Err(error::RecvError(())); | ||
} | ||
let new_version = state.version(); | ||
|
||
// Load the version from the state | ||
let new_version = self.shared.version(); | ||
Ok(self.version != new_version) |
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.
Since you've split the closed bit out from the atomic, this introduces extra possibilities for race conditions causing incorrect behavior. I would need some time to think about whether this is still correct.
It's interesting that the |
This fails the watch smoke test:
|
@hawkw Those are tests that are supposed to panic, so they print a panic but don't fail. |
This implementation is currently incorrect. I'll close this PR since there has been no activity for a while. In either case, thanks for taking the time to submit a PR. If you want to continue working on it in the future, then please feel free to reopen or post a new PR. |
Here I'm implement Clone for watch::Sender, which makes it mpsc
TODO
Motivation
See #4809
Solution
I've implemented one of the suggestions in the issue, which is to keep track of the number of Senders separate from the version.
Open questions: are there other methods that need to be added? E.g. 'upgrading' a receiver to a sender or getting the number of current Senders