-
-
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
watch::Sender: Modify and send value conditionally #4591
Conversation
acd4cdc
to
1f3b5a3
Compare
Getting the doctest right was trickier than expected. But now it is more restrictive and also considers the changed flag. |
A breaking change in the main Tokio crate is not going to happen. |
What do you suggest? Add a new function |
A new function would be possible. |
Add a function that is more versatile than send_modify(). The result of the passed closure indicates if the mutably borrowed value has actually been modified or not. Receivers are only notified if the value has been modified as indicated by the sender. Signed-off-by: Uwe Klotz <uwe.klotz@slowtec.de>
1f3b5a3
to
c713603
Compare
I have added a new function, force pushed, and updated the PR description. The name of the new function and its parameter have been chosen to be readable and to reflect the expected behavior. Other suggestions are always welcome. |
Someone pointed out that that can already be implemented using |
How could this work reliably? Upgrading a read lock to a write lock could cause deadlocks. Therefore we need to acquire a write lock right from the start without marking the value as dirty. |
The watch channel is single-producer. With only one sender, there's no race even if you unlock the read lock to take the write lock. |
Doesn't work for my FRP use case where I am sharing the Or do I need to use a full featured MPMC queue for this purpose? |
I suppose it is true that you can have multiple senders by wrapping it in an |
Avoid using mutable local variables.
0c360a4
to
6bd5cc5
Compare
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.
Alright, I think this change looks good. It's annoying that we've ended up with so many different send methods, but I suppose it is fine. I do have one comment regarding the docs though.
tokio/src/sync/watch.rs
Outdated
/// The closure that modifies the value must return `true` if the | ||
/// value has actually been modified. It should only return `false` | ||
/// if the value is guaranteed to be unnmodified despite the mutable | ||
/// borrow. Receivers are only notified if the value has been modified. |
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.
Although not modifying it when you return false
is the intended use-case, I still think we should document what happens if you modify the value and then return false
.
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.
While we are at it: Should we remove the redundancy in the docs and refer to the more versatile send_if_modified()
in the docs for send_modify()
? The docs would then basically reflect the forwarding of the implementation.
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.
Any improvements to the docs you can come up with would be good! Let me know when you think the docs are ready.
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 have revised and aligned the docs of both functions, highlighting their differences and similarities. Since I am not a native speaker someone should verify.
Removing the redundancies would be difficult. Copying the shared parts should be ok to keep the descriptions readable.
Hopefully, this is now the most universal variant. Envisioning all possible use cases right from the start is always difficult. Capturing intermediate results is possible by storing them in the (mutable) environment of the closure. Therefore I am confident that the boolean result extension is sufficient here. Aligning the names by renaming it to |
Add a function that is more versatile than send_modify(). The result of the passed closure indicates if the mutably borrowed value has actually been modified or not. Receivers are only notified if the value has been modified as indicated by the sender. Signed-off-by: Uwe Klotz <uwe.klotz@slowtec.de>
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [tokio](https://tokio.rs) ([source](https://github.com/tokio-rs/tokio)) | dependencies | minor | `1.18.2` -> `1.19.1` | | [tokio](https://tokio.rs) ([source](https://github.com/tokio-rs/tokio)) | dev-dependencies | minor | `1.18.2` -> `1.19.1` | --- ### Release Notes <details> <summary>tokio-rs/tokio</summary> ### [`v1.19.1`](https://github.com/tokio-rs/tokio/releases/tag/tokio-1.19.1) [Compare Source](tokio-rs/tokio@tokio-1.19.0...tokio-1.19.1) ##### 1.19.1 (June 5, 2022) This release fixes a bug in `Notified::enable`. ([#​4747]) [#​4747]: tokio-rs/tokio#4747 ### [`v1.19.0`](https://github.com/tokio-rs/tokio/releases/tag/tokio-1.19.0) [Compare Source](tokio-rs/tokio@tokio-1.18.2...tokio-1.19.0) ##### 1.19.0 (June 3, 2022) ##### Added - runtime: add `is_finished` method for `JoinHandle` and `AbortHandle` ([#​4709]) - runtime: make global queue and event polling intervals configurable ([#​4671]) - sync: add `Notified::enable` ([#​4705]) - sync: add `watch::Sender::send_if_modified` ([#​4591]) - sync: add resubscribe method to broadcast::Receiver ([#​4607]) - net: add `take_error` to `TcpSocket` and `TcpStream` ([#​4739]) ##### Changed - io: refactor out usage of Weak in the io handle ([#​4656]) ##### Fixed - macros: avoid starvation in `join!` and `try_join!` ([#​4624]) ##### Documented - runtime: clarify semantics of tasks outliving `block_on` ([#​4729]) - time: fix example for `MissedTickBehavior::Burst` ([#​4713]) ##### Unstable - metrics: correctly update atomics in `IoDriverMetrics` ([#​4725]) - metrics: fix compilation with unstable, process, and rt, but without net ([#​4682]) - task: add `#[track_caller]` to `JoinSet`/`JoinMap` ([#​4697]) - task: add `Builder::{spawn_on, spawn_local_on, spawn_blocking_on}` ([#​4683]) - task: add `consume_budget` for cooperative scheduling ([#​4498]) - task: add `join_set::Builder` for configuring `JoinSet` tasks ([#​4687]) - task: update return value of `JoinSet::join_one` ([#​4726]) [#​4498]: tokio-rs/tokio#4498 [#​4591]: tokio-rs/tokio#4591 [#​4607]: tokio-rs/tokio#4607 [#​4624]: tokio-rs/tokio#4624 [#​4656]: tokio-rs/tokio#4656 [#​4671]: tokio-rs/tokio#4671 [#​4682]: tokio-rs/tokio#4682 [#​4683]: tokio-rs/tokio#4683 [#​4687]: tokio-rs/tokio#4687 [#​4697]: tokio-rs/tokio#4697 [#​4705]: tokio-rs/tokio#4705 [#​4709]: tokio-rs/tokio#4709 [#​4713]: tokio-rs/tokio#4713 [#​4725]: tokio-rs/tokio#4725 [#​4726]: tokio-rs/tokio#4726 [#​4729]: tokio-rs/tokio#4729 [#​4739]: tokio-rs/tokio#4739 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [x] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox. --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Co-authored-by: cabr2-bot <cabr2.help@gmail.com> Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1394 Reviewed-by: crapStone <crapstone@noreply.codeberg.org> Co-authored-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org> Co-committed-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
TODO
Often times you need to check preconditions and constraints before actually modifying a value. Currently receivers are notified unconditionally, even if the value has not been modified.
This PR adds a function
send_if_modified()
that is more versatile thansend_modify()
. The result of the passed closure indicates if the mutably borrowed value has actually been modified or not. Receivers are only notified if the value has been modified as indicated by the sender.Signed-off-by: Uwe Klotz uwe.klotz@slowtec.de