Skip to content
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: add watch::Receiver::wait_for #5606

Closed
carllerche opened this issue Apr 6, 2023 · 2 comments · Fixed by #5611
Closed

sync: add watch::Receiver::wait_for #5606

carllerche opened this issue Apr 6, 2023 · 2 comments · Fixed by #5611
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. E-easy Call for participation: Experience needed to fix: Easy / not much E-help-wanted Call for participation: Help is requested to fix this issue. M-sync Module: tokio/sync

Comments

@carllerche
Copy link
Member

carllerche commented Apr 6, 2023

Correct use of watch::Receiver requires first checking the current value, then waiting for changes. Forgetting the first check can lead to race conditions.

Consider a watch used to track shutdown notification. The following would result in the shutdown notification being lost:

let (tx, _rx) = watch::channel(false);

tx.send(true)?;

let rx = tx.subscribe();

rx.changed().await?; // hang forever

We could add some APIs that make it easier to wait for specific values.

Roughly:

async fn wait_for(&mut self, f: impl FnMut(&T) -> bool) {
    loop {
        if f(self.borrow_and_update()) {
            return;
        }

        self.changed().await;
    }
}

Then, using a watch to await a shutdown signal becomes:

rx.wait_for(|is_shutdown| *is_shutdown).await;

I also imagine there could be other APIs, like wait_and_map or something that takes fn (&T) -> Option<U>.

@carllerche carllerche added A-tokio Area: The main tokio crate C-feature-request Category: A feature request. M-sync Module: tokio/sync E-help-wanted Call for participation: Help is requested to fix this issue. E-easy Call for participation: Experience needed to fix: Easy / not much labels Apr 6, 2023
@debadree25
Copy link
Contributor

Hey! I would like to give this a try (beginner here hence seeking advise here first) so if I understand correctly we would add the API here tokio/src/sync/watch.rs ?

@Darksonn
Copy link
Contributor

Darksonn commented Apr 9, 2023

Yes, that's correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. E-easy Call for participation: Experience needed to fix: Easy / not much E-help-wanted Call for participation: Help is requested to fix this issue. M-sync Module: tokio/sync
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants