pub struct TaskTracker { /* private fields */ }Expand description
A task tracker used for waiting until tasks exit.
This is usually used together with a cancellation token to implement graceful shutdown. The
cancellation token is used to signal to tasks that they should shut down, and the
TaskTracker is used to wait for them to finish shutting down. For tokio runtime, there is a
CancellationToken in the tokio-util crate that can be used for this purpose. Otherwise,
consider using an mpsc channel as a cancellation token.
The TaskTracker will also keep track of a closed boolean. This is used to handle the case
where the TaskTracker is empty, but we don’t want to shut down yet. This means that the
wait method will wait until both of the following happen at the same time:
- The
TaskTrackermust be closed using theclosemethod. - The
TaskTrackermust be empty, that is, all tasks that it is tracking must have exited.
When a call to wait returns, it is guaranteed that all tracked tasks have exited and that
the destructor of the future has finished running.
§Examples
§Spawn tasks and wait for them to exit
use async_task_tracker::TaskTracker;
async fn run() {
let tracker = TaskTracker::new();
for i in 0..10 {
my_runtime_spawn(tracker.track_future(async move {
println!("Task {} is running!", i);
}));
}
// Once we spawned everything, we close the tracker.
tracker.close();
// Wait for everything to finish.
tracker.wait().await;
println!("This is printed after all of the tasks.");
}
fn my_runtime_spawn(_fut: impl std::future::Future<Output = ()> + 'static) {}Implementations§
Source§impl TaskTracker
impl TaskTracker
Sourcepub fn wait(&self) -> TaskTrackerWaitFuture<'_> ⓘ
pub fn wait(&self) -> TaskTrackerWaitFuture<'_> ⓘ
Waits until this TaskTracker is both closed and empty.
If the TaskTracker is already closed and empty when this method is called, then it
returns immediately.
The wait future is resistant against ABA problems. That is, if the TaskTracker
becomes both closed and empty for a short amount of time, then it is guarantee that all
wait futures that were created before the short time interval will trigger, even if they
are not polled during that short time interval.
§Cancel safety
This method is cancel safe.
However, the resistance against ABA problems is lost when using wait as the
condition in a tokio::select! loop.
Sourcepub fn close(&self) -> bool
pub fn close(&self) -> bool
Close this TaskTracker.
This allows wait futures to complete. It does not prevent you from spawning new tasks.
Returns true if this closed the TaskTracker, or false if it was already closed.
Sourcepub fn reopen(&self) -> bool
pub fn reopen(&self) -> bool
Reopen this TaskTracker.
This prevents wait futures from completing even if the TaskTracker is empty.
Returns true if this reopened the TaskTracker, or false if it was already open.
Sourcepub fn track_future<F: Future>(&self, future: F) -> TrackedFuture<F> ⓘ
pub fn track_future<F: Future>(&self, future: F) -> TrackedFuture<F> ⓘ
Track the provided future.
The returned TrackedFuture will count as a task tracked by this collection, and will
prevent calls to wait from returning until the task is dropped.
The task is removed from the collection when it is dropped, not when poll returns
Poll::Ready.
§Examples
Track a spawned future.
use async_task_tracker::TaskTracker;
let tracker = TaskTracker::new();
my_runtime_spawn(tracker.track_future(my_async_fn()));Sourcepub fn token(&self) -> TaskTrackerToken
pub fn token(&self) -> TaskTrackerToken
Creates a TaskTrackerToken representing a task tracked by this TaskTracker.
This token is a lower-level utility than the spawn methods. Each token is considered to
correspond to a task. As long as the token exists, the TaskTracker cannot complete.
Furthermore, the count returned by the len method will include the tokens in the count.
Dropping the token indicates to the TaskTracker that the task has exited.
Sourcepub fn ptr_eq(left: &TaskTracker, right: &TaskTracker) -> bool
pub fn ptr_eq(left: &TaskTracker, right: &TaskTracker) -> bool
Returns true if both task trackers correspond to the same set of tasks.
§Examples
use async_task_tracker::TaskTracker;
let tracker_1 = TaskTracker::new();
let tracker_2 = TaskTracker::new();
let tracker_1_clone = tracker_1.clone();
assert!(TaskTracker::ptr_eq(&tracker_1, &tracker_1_clone));
assert!(!TaskTracker::ptr_eq(&tracker_1, &tracker_2));Trait Implementations§
Source§impl Clone for TaskTracker
impl Clone for TaskTracker
Source§fn clone(&self) -> TaskTracker
fn clone(&self) -> TaskTracker
Returns a new TaskTracker that tracks the same set of tasks.
Since the new TaskTracker shares the same set of tasks, changes to one set are visible in
all other clones.
§Examples
use async_task_tracker::TaskTracker;
async fn run() {
let tracker = TaskTracker::new();
let cloned = tracker.clone();
// Spawns on `tracker` are visible in `cloned`.
my_runtime_spawn(tracker.track_future(std::future::pending::<()>()));
assert_eq!(cloned.len(), 1);
// Spawns on `cloned` are visible in `tracker`.
my_runtime_spawn(tracker.track_future(std::future::pending::<()>()));
assert_eq!(tracker.len(), 2);
// Calling `close` is visible to `cloned`.
tracker.close();
assert!(cloned.is_closed());
// Calling `reopen` is visible to `tracker`.
cloned.reopen();
assert!(!tracker.is_closed());
}
fn my_runtime_spawn(_fut: impl std::future::Future<Output = ()> + 'static) {}1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for TaskTracker
impl Debug for TaskTracker
Source§impl Default for TaskTracker
impl Default for TaskTracker
Source§fn default() -> TaskTracker
fn default() -> TaskTracker
Creates a new TaskTracker.
The TaskTracker will start out as open.