-
-
Notifications
You must be signed in to change notification settings - Fork 194
refactor: add WaitGroup for waiting for a dynamic set of tasks #2046
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
Merged
+204
−10
Merged
Changes from 13 commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
c6eff7f
feat: WaitGuard for waiting on a dynamically-determined group of tasks
katrinafyi eadf9af
race doesnt work
katrinafyi a210d77
x
katrinafyi 1598c8c
fix deadlock
katrinafyi fd2f5d3
fmt
katrinafyi 47921b0
i think the deadlock was due to std::sync::Arc internally using
katrinafyi 1df0a87
fmt
katrinafyi 99d7fa1
lint
katrinafyi a5b9816
l2
katrinafyi 79016f4
infallible
katrinafyi 022b9e0
comment
katrinafyi 9623607
take_until
katrinafyi dc6966c
cmt
katrinafyi 74046a9
Merge branch 'master' into waitgroup
katrinafyi 6ad9092
working on example...... [no ci]
katrinafyi c53e913
fib
katrinafyi 5792470
use Never instead of Infallible
katrinafyi b27a34f
fix wawrnings
katrinafyi 10f3c74
considered
katrinafyi 0439d47
incr channel can be bounded to 1, because it gets polled immediately
katrinafyi 2560b34
whitespace
katrinafyi 87c19c9
move example into doctest
katrinafyi 7718cc8
`use tokio_stream as _` when not doctest
katrinafyi fc086fe
Merge branch 'master' into waitgroup
katrinafyi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| //! Facility to wait for a dynamic set of tasks to complete, with a single | ||
| //! waiter and multiple waitees (things that are waited for). Notably, each | ||
| //! waitee can also start more work to be waited for. | ||
| //! | ||
| //! # Implementation Details | ||
| //! | ||
| //! The implementation of waiting in this module is just a wrapper around | ||
| //! [`tokio::sync::mpsc::channel`]. A [`WaitGroup`] holds the unique | ||
| //! [`tokio::sync::mpsc::Receiver`] and each [`WaitGuard`] holds a | ||
| //! [`tokio::sync::mpsc::Sender`]. Despite this simple implementation, the | ||
| //! [`WaitGroup`] and [`WaitGuard`] wrappers are useful to make this discoverable. | ||
|
|
||
| use std::convert::Infallible; | ||
| use tokio::sync::mpsc::{Receiver, Sender, channel}; | ||
|
|
||
| /// Manager for a particular wait group. This can spawn a number of [`WaitGuard`]s | ||
| /// and it can then wait for them to all complete. | ||
| /// | ||
| /// Each [`WaitGroup`] is single-use—calling [`WaitGroup::wait`] to start | ||
| /// waiting consumes the [`WaitGroup`]. Additionally, once all [`WaitGuard`]s | ||
| /// have been dropped, it is not possible to create any more [`WaitGuard`]s. | ||
| #[derive(Debug)] | ||
| pub struct WaitGroup { | ||
| /// [`Receiver`] is held to wait for multiple [`Sender`]s and detect | ||
| /// when they have closed. The [`Infallible`] type means no value can/will | ||
| /// ever be received through the channel. | ||
| recv: Receiver<Infallible>, | ||
| } | ||
|
|
||
| /// RAII guard held by a task which is being waited for. | ||
| /// | ||
| /// The existence of values of this type represents outstanding work for | ||
| /// its corresponding [`WaitGroup`]. | ||
| /// | ||
| /// A [`WaitGuard`] can be cloned using [`WaitGuard::clone`]. This allows | ||
| /// a task to spawn additional tasks, recursively. | ||
| #[derive(Clone, Debug)] | ||
| pub struct WaitGuard { | ||
| /// [`Sender`] is held to keep the [`Receiver`] end open (stored in [`WaitGroup`]). | ||
| /// The dropping of all senders will cause the receiver to detect and close. | ||
| /// The [`Infallible`] type means no value can/will ever be sent through the channel. | ||
| _send: Sender<Infallible>, | ||
| } | ||
|
|
||
| impl WaitGroup { | ||
| /// Creates a new [`WaitGroup`] and its first associated [`WaitGuard`]. | ||
| /// | ||
| /// Note that [`WaitGroup`] itself has no ability to create new guards. | ||
| /// If needed, new guards should be created by cloning the returned [`WaitGuard`]. | ||
| #[must_use] | ||
| pub fn new() -> (Self, WaitGuard) { | ||
| let (send, recv) = channel(1); | ||
| (Self { recv }, WaitGuard { _send: send }) | ||
| } | ||
|
|
||
| /// Waits, asynchronously, until all the associated [`WaitGuard`]s have finished. | ||
| pub async fn wait(mut self) { | ||
| let None = self.recv.recv().await; | ||
thomas-zahner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.