Struct JoinSet
pub struct JoinSet<T> { /* private fields */ }
rt only.A collection of tasks spawned on a Tokio runtime.
A JoinSet can be used to await the completion of some or all of the tasks in the set. The set is not ordered, and the tasks will be returned in the order they complete.
All of the tasks must have the same return type T.
When the JoinSet is dropped, all tasks in the JoinSet are immediately aborted.
Examples
Spawn multiple tasks and wait for them.
use tokio::task::JoinSet;
let mut set = JoinSet::new();
for i in 0..10 {
set.spawn(async move { i });
}
let mut seen = [false; 10];
while let Some(res) = set.join_next().await {
let idx = res.unwrap();
seen[idx] = true;
}
for i in 0..10 {
assert!(seen[i]);
}Task ID guarantees
While a task is tracked in a JoinSet, that task’s ID is unique relative to all other running tasks in Tokio. For this purpose, tracking a task in a JoinSet is equivalent to holding a JoinHandle to it. See the task ID documentation for more info.
Implementations
impl<T> JoinSet<T>
impl<T: 'static> JoinSet<T>
pub fn build_task(&mut self) -> Builder<'_, T>
tokio_unstable and crate feature tracing only.Returns a Builder that can be used to configure a task prior to spawning it on this JoinSet.
Examples
use tokio::task::JoinSet;
#[tokio::main]
async fn main() -> std::io::Result<()> {
let mut set = JoinSet::new();
// Use the builder to configure a task's name before spawning it.
set.build_task()
.name("my_task")
.spawn(async { /* ... */ })?;
Ok(())
}pub fn spawn<F>(&mut self, task: F) -> AbortHandle
Spawn the provided task on the JoinSet, returning an AbortHandle that can be used to remotely cancel the task.
The provided future will start running in the background immediately when this method is called, even if you don’t await anything on this JoinSet.
Panics
This method panics if called outside of a Tokio runtime.
pub fn spawn_on<F>(&mut self, task: F, handle: &Handle) -> AbortHandle
Spawn the provided task on the provided runtime and store it in this JoinSet returning an AbortHandle that can be used to remotely cancel the task.
The provided future will start running in the background immediately when this method is called, even if you don’t await anything on this JoinSet.
pub fn spawn_local<F>(&mut self, task: F) -> AbortHandlewhere F: Future<Output = T> + 'static,
Spawn the provided task on the current LocalSet or LocalRuntime and store it in this JoinSet, returning an AbortHandle that can be used to remotely cancel the task.
The provided future will start running in the background immediately when this method is called, even if you don’t await anything on this JoinSet.
Panics
This method panics if it is called outside of a LocalSet or LocalRuntime.
pub fn spawn_local_on<F>( &mut self, task: F, local_set: &LocalSet, ) -> AbortHandlewhere F: Future<Output = T> + 'static,
Spawn the provided task on the provided LocalSet and store it in this JoinSet, returning an AbortHandle that can be used to remotely cancel the task.
Unlike the spawn_local method, this method may be used to spawn local tasks on a LocalSet that is not currently running. The provided future will start running whenever the LocalSet is next started.
pub fn spawn_blocking<F>(&mut self, f: F) -> AbortHandle
Spawn the blocking code on the blocking threadpool and store it in this JoinSet, returning an AbortHandle that can be used to remotely cancel the task.
Examples
Spawn multiple blocking tasks and wait for them.
use tokio::task::JoinSet;
#[tokio::main]
async fn main() {
let mut set = JoinSet::new();
for i in 0..10 {
set.spawn_blocking(move || { i });
}
let mut seen = [false; 10];
while let Some(res) = set.join_next().await {
let idx = res.unwrap();
seen[idx] = true;
}
for i in 0..10 {
assert!(seen[i]);
}
}Panics
This method panics if called outside of a Tokio runtime.
pub fn spawn_blocking_on<F>(&mut self, f: F, handle: &Handle) -> AbortHandle
Spawn the blocking code on the blocking threadpool of the provided runtime and store it in this JoinSet, returning an AbortHandle that can be used to remotely cancel the task.
pub async fn join_next(&mut self) -> Option<Result<T, JoinError>>
Waits until one of the tasks in the set completes and returns its output.
Returns None if the set is empty.
Cancel safety
This method is cancel safe. If join_next is used as a branch in tokio::select! and another branch completes first, it is guaranteed that no tasks were removed from this JoinSet.
pub async fn join_next_with_id(&mut self) -> Option<Result<(Id, T), JoinError>>
Waits until one of the tasks in the set completes and returns its output, along with the task ID of the completed task.
Returns None if the set is empty.
When this method returns an error, then the id of the task that failed can be accessed using the JoinError::id method.
Cancel safety
This method is cancel safe. If join_next_with_id is used as a branch in tokio::select! and another branch completes first, it is guaranteed that no tasks were removed from this JoinSet.
pub fn try_join_next(&mut self) -> Option<Result<T, JoinError>>
Tries to join one of the tasks in the set that has completed and return its output.
Returns None if there are no completed tasks, or if the set is empty.
pub fn try_join_next_with_id(&mut self) -> Option<Result<(Id, T), JoinError>>
Tries to join one of the tasks in the set that has completed and return its output, along with the task ID of the completed task.
Returns None if there are no completed tasks, or if the set is empty.
When this method returns an error, then the id of the task that failed can be accessed using the JoinError::id method.
pub async fn shutdown(&mut self)
pub async fn join_all(self) -> Vec<T>
Awaits the completion of all tasks in this JoinSet, returning a vector of their results.
The results will be stored in the order they completed not the order they were spawned. This is a convenience method that is equivalent to calling join_next in a loop. If any tasks on the JoinSet fail with an JoinError, then this call to join_all will panic and all remaining tasks on the JoinSet are cancelled. To handle errors in any other way, manually call join_next in a loop.
Examples
Spawn multiple tasks and join_all them.
use tokio::task::JoinSet;
use std::time::Duration;
let mut set = JoinSet::new();
for i in 0..3 {
set.spawn(async move {
tokio::time::sleep(Duration::from_secs(3 - i)).await;
i
});
}
let output = set.join_all().await;
assert_eq!(output, vec![2, 1, 0]);Equivalent implementation of join_all, using join_next and loop.
use tokio::task::JoinSet;
use std::panic;
let mut set = JoinSet::new();
for i in 0..3 {
set.spawn(async move {i});
}
let mut output = Vec::new();
while let Some(res) = set.join_next().await{
match res {
Ok(t) => output.push(t),
Err(err) if err.is_panic() => panic::resume_unwind(err.into_panic()),
Err(err) => panic!("{err}"),
}
}
assert_eq!(output.len(),3);pub fn abort_all(&mut self)
Aborts all tasks on this JoinSet.
This does not remove the tasks from the JoinSet. To wait for the tasks to complete cancellation, you should call join_next in a loop until the JoinSet is empty.
pub fn detach_all(&mut self)
Removes all tasks from this JoinSet without aborting them.
The tasks removed by this call will continue to run in the background even if the JoinSet is dropped.
pub fn poll_join_next( &mut self, cx: &mut Context<'_>, ) -> Poll<Option<Result<T, JoinError>>>
Polls for one of the tasks in the set to complete.
If this returns Poll::Ready(Some(_)), then the task that completed is removed from the set.
When the method returns Poll::Pending, the Waker in the provided Context is scheduled to receive a wakeup when a task in the JoinSet completes. Note that on multiple calls to poll_join_next, only the Waker from the Context passed to the most recent call is scheduled to receive a wakeup.
Returns
This function returns:
-
Poll::Pendingif theJoinSetis not empty but there is no task whose output is available right now. -
Poll::Ready(Some(Ok(value)))if one of the tasks in thisJoinSethas completed. Thevalueis the return value of one of the tasks that completed. -
Poll::Ready(Some(Err(err)))if one of the tasks in thisJoinSethas panicked or been aborted. Theerris theJoinErrorfrom the panicked/aborted task. -
Poll::Ready(None)if theJoinSetis empty.
Note that this method may return Poll::Pending even if one of the tasks has completed. This can happen if the coop budget is reached.
pub fn poll_join_next_with_id( &mut self, cx: &mut Context<'_>, ) -> Poll<Option<Result<(Id, T), JoinError>>>
Polls for one of the tasks in the set to complete.
If this returns Poll::Ready(Some(_)), then the task that completed is removed from the set.
When the method returns Poll::Pending, the Waker in the provided Context is scheduled to receive a wakeup when a task in the JoinSet completes. Note that on multiple calls to poll_join_next, only the Waker from the Context passed to the most recent call is scheduled to receive a wakeup.
Returns
This function returns:
-
Poll::Pendingif theJoinSetis not empty but there is no task whose output is available right now. -
Poll::Ready(Some(Ok((id, value))))if one of the tasks in thisJoinSethas completed. Thevalueis the return value of one of the tasks that completed, andidis the task ID of that task. -
Poll::Ready(Some(Err(err)))if one of the tasks in thisJoinSethas panicked or been aborted. Theerris theJoinErrorfrom the panicked/aborted task. -
Poll::Ready(None)if theJoinSetis empty.
Note that this method may return Poll::Pending even if one of the tasks has completed. This can happen if the coop budget is reached.
Trait Implementations
impl<T, F> Extend<F> for JoinSet<T>
Extend a JoinSet with futures from an iterator.
This is equivalent to calling JoinSet::spawn on each element of the iterator.
Examples
use tokio::task::JoinSet;
#[tokio::main]
async fn main() {
let mut set: JoinSet<_> = (0..5).map(|i| async move { i }).collect();
set.extend((5..10).map(|i| async move { i }));
let mut seen = [false; 10];
while let Some(res) = set.join_next().await {
let idx = res.unwrap();
seen[idx] = true;
}
for i in 0..10 {
assert!(seen[i]);
}
}fn extend<I>(&mut self, iter: I)where I: IntoIterator<Item = F>,
fn extend_one(&mut self, item: A)
extend_one)
fn extend_reserve(&mut self, additional: usize)
extend_one)
impl<T, F> FromIterator<F> for JoinSet<T>
Collect an iterator of futures into a JoinSet.
This is equivalent to calling JoinSet::spawn on each element of the iterator.
Examples
The main example from JoinSet’s documentation can also be written using collect:
use tokio::task::JoinSet;
let mut set: JoinSet<_> = (0..10).map(|i| async move { i }).collect();
let mut seen = [false; 10];
while let Some(res) = set.join_next().await {
let idx = res.unwrap();
seen[idx] = true;
}
for i in 0..10 {
assert!(seen[i]);
}fn from_iter<I: IntoIterator<Item = F>>(iter: I) -> Self
Auto Trait Implementations
impl<T> !RefUnwindSafe for JoinSet<T>
impl<T> !UnwindSafe for JoinSet<T>
impl<T> Freeze for JoinSet<T>
impl<T> Send for JoinSet<T>where T: Send,
impl<T> Sync for JoinSet<T>where T: Send,
impl<T> Unpin for JoinSet<T>
impl<T> UnsafeUnpin for JoinSet<T>
Blanket Implementations
impl<T> BorrowMut<T> for Twhere T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
impl<T> Instrument for T
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
impl<T> WithSubscriber for T
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/task/join_set/struct.JoinSet.html