From b248be2879dfc5e19d1b82561486efede74172ba Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Sun, 23 Oct 2022 20:25:12 +0200 Subject: [PATCH] task: document that spawned tasks execute immedaitely (#5117) --- tokio/src/runtime/handle.rs | 4 ++++ tokio/src/runtime/mod.rs | 4 ++++ tokio/src/runtime/task/join.rs | 6 ++++-- tokio/src/task/join_set.rs | 19 ++++++++++++++++++ tokio/src/task/local.rs | 26 ++++++++++++++++++++----- tokio/src/task/spawn.rs | 35 ++++++++++++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 7 deletions(-) diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs index c7e3ce9ec37..5f5603f8a0b 100644 --- a/tokio/src/runtime/handle.rs +++ b/tokio/src/runtime/handle.rs @@ -114,6 +114,10 @@ impl Handle { /// thread pool. The thread pool is then responsible for polling the future /// until it completes. /// + /// You do not have to `.await` the returned `JoinHandle` to make the + /// provided future start execution. It will start running in the background + /// immediately when `spawn` is called. + /// /// See [module level][mod] documentation for more details. /// /// [mod]: index.html diff --git a/tokio/src/runtime/mod.rs b/tokio/src/runtime/mod.rs index 1ca9b944152..14b6f01d8aa 100644 --- a/tokio/src/runtime/mod.rs +++ b/tokio/src/runtime/mod.rs @@ -382,6 +382,10 @@ cfg_rt! { /// thread pool. The thread pool is then responsible for polling the future /// until it completes. /// + /// You do not have to `.await` the returned `JoinHandle` to make the + /// provided future start execution. It will start running in the + /// background immediately when `spawn` is called. + /// /// See [module level][mod] documentation for more details. /// /// [mod]: index.html diff --git a/tokio/src/runtime/task/join.rs b/tokio/src/runtime/task/join.rs index 927be1acf3e..b2138b14596 100644 --- a/tokio/src/runtime/task/join.rs +++ b/tokio/src/runtime/task/join.rs @@ -10,8 +10,10 @@ use std::task::{Context, Poll, Waker}; cfg_rt! { /// An owned permission to join on a task (await its termination). /// - /// This can be thought of as the equivalent of [`std::thread::JoinHandle`] for - /// a task rather than a thread. + /// This can be thought of as the equivalent of [`std::thread::JoinHandle`] + /// for a Tokio task rather than a thread. You do not need to `.await` the + /// `JoinHandle` to make the task execute — it will start running in the + /// background immediately. /// /// A `JoinHandle` *detaches* the associated task when it is dropped, which /// means that there is no longer any handle to the task, and no way to `join` diff --git a/tokio/src/task/join_set.rs b/tokio/src/task/join_set.rs index b10b5a6b456..f18130228dc 100644 --- a/tokio/src/task/join_set.rs +++ b/tokio/src/task/join_set.rs @@ -120,6 +120,10 @@ impl JoinSet { /// Spawn the provided task on the `JoinSet`, returning an [`AbortHandle`] /// that can be used to remotely cancel the task. /// + /// You do not have to `.await` the returned `JoinHandle` to make the + /// provided future start execution. It will start running in the background + /// immediately when `spawn` is called. + /// /// # Panics /// /// This method panics if called outside of a Tokio runtime. @@ -139,6 +143,10 @@ impl JoinSet { /// `JoinSet` returning an [`AbortHandle`] that can be used to remotely /// cancel the task. /// + /// You do not have to `.await` the returned `JoinHandle` to make the + /// provided future start execution. It will start running in the background + /// immediately when `spawn_on` is called. + /// /// [`AbortHandle`]: crate::task::AbortHandle #[track_caller] pub fn spawn_on(&mut self, task: F, handle: &Handle) -> AbortHandle @@ -154,6 +162,10 @@ impl JoinSet { /// `JoinSet`, returning an [`AbortHandle`] that can be used to remotely /// cancel the task. /// + /// You do not have to `.await` the returned `JoinHandle` to make the + /// provided future start execution. It will start running in the background + /// immediately when `spawn_local` is called. + /// /// # Panics /// /// This method panics if it is called outside of a `LocalSet`. @@ -173,8 +185,15 @@ impl JoinSet { /// 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 when the `LocalSet` is _not_ running. You do not have to `.await` + /// the returned `JoinHandle` to make the provided future start execution. + /// It will start running immediately whenever the `LocalSet` is next + /// started. + /// /// [`LocalSet`]: crate::task::LocalSet /// [`AbortHandle`]: crate::task::AbortHandle + /// [`spawn_local`]: Self::spawn_local #[track_caller] pub fn spawn_local_on(&mut self, task: F, local_set: &LocalSet) -> AbortHandle where diff --git a/tokio/src/task/local.rs b/tokio/src/task/local.rs index 4a2209cd2e8..185ac9d2679 100644 --- a/tokio/src/task/local.rs +++ b/tokio/src/task/local.rs @@ -283,14 +283,21 @@ struct LocalData { } cfg_rt! { - /// Spawns a `!Send` future on the local task set. + /// Spawns a `!Send` future on the current [`LocalSet`]. /// - /// The spawned future will be run on the same thread that called `spawn_local.` - /// This may only be called from the context of a local task set. + /// The spawned future will run on the same thread that called `spawn_local`. + /// + /// You do not have to `.await` the returned `JoinHandle` to make the + /// provided future start execution. It will start running in the background + /// immediately when `spawn_local` is called. /// /// # Panics /// - /// - This function panics if called outside of a local task set. + /// This function panics if called outside of a [`LocalSet`]. + /// + /// Note that if [`tokio::spawn`] is used from within a `LocalSet`, the + /// resulting new task will _not_ be inside the `LocalSet`, so you must use + /// use `spawn_local` if you want to stay within the `LocalSet`. /// /// # Examples /// @@ -314,6 +321,9 @@ cfg_rt! { /// }).await; /// } /// ``` + /// + /// [`LocalSet`]: struct@crate::task::LocalSet + /// [`tokio::spawn`]: fn@crate::task::spawn #[track_caller] pub fn spawn_local(future: F) -> JoinHandle where @@ -401,7 +411,13 @@ impl LocalSet { /// This task is guaranteed to be run on the current thread. /// /// Unlike the free function [`spawn_local`], this method may be used to - /// spawn local tasks when the task set is _not_ running. For example: + /// spawn local tasks when the `LocalSet` is _not_ running. You do not have + /// to `.await` the returned `JoinHandle` to make the provided future start + /// execution. It will start running immediately whenever the `LocalSet` is + /// next started. + /// + /// # Examples + /// /// ```rust /// use tokio::task; /// diff --git a/tokio/src/task/spawn.rs b/tokio/src/task/spawn.rs index 3fdd0357e80..5db11a47994 100644 --- a/tokio/src/task/spawn.rs +++ b/tokio/src/task/spawn.rs @@ -7,6 +7,10 @@ cfg_rt! { /// Spawns a new asynchronous task, returning a /// [`JoinHandle`](super::JoinHandle) for it. /// + /// You do not have to `.await` the returned `JoinHandle` to make the + /// provided future start execution. It will start running in the background + /// immediately when `spawn` is called. + /// /// Spawning a task enables the task to execute concurrently to other tasks. The /// spawned task may execute on the current thread, or it may be sent to a /// different thread to be executed. The specifics depend on the current @@ -50,6 +54,37 @@ cfg_rt! { /// } /// ``` /// + /// To run multiple tasks in parallel and receive their results, join + /// handles can be stored in a vector. + /// ``` + /// # #[tokio::main(flavor = "current_thread")] async fn main() { + /// async fn my_background_op(id: i32) -> String { + /// let s = format!("Starting background task {}.", id); + /// println!("{}", s); + /// s + /// } + /// + /// let ops = vec![1, 2, 3]; + /// let mut tasks = Vec::with_capacity(ops.len()); + /// for op in ops { + /// // This call will make them start running in the background + /// // immediately. + /// tasks.push(tokio::spawn(my_background_op(op))); + /// } + /// + /// let mut outputs = Vec::with_capacity(tasks.len()); + /// for task in tasks { + /// outputs.push(task.await.unwrap()); + /// } + /// println!("{:?}", outputs); + /// # } + /// ``` + /// This example pushes the tasks to `outputs` in the order they were + /// started in. If you do not care about the ordering of the outputs, then + /// you can also use a [`JoinSet`]. + /// + /// [`JoinSet`]: struct@crate::task::JoinSet + /// /// # Panics /// /// Panics if called from **outside** of the Tokio runtime.