pub struct Scope { /* private fields */ }Expand description
A Scope for spawning Tokio Tasks.
When the Scope is dropped, any tasks which are still executing are cancelled. If you want to cancel all tasks sooner, you can use Scope::cancel().
Implementations§
Source§impl Scope
impl Scope
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new scoped task spawner
Tasks may be cancelled manually, using cancel(), or automatically
when the Scope is dropped.
Sourcepub fn spawn<F, R>(&self, future: F) -> JoinHandle<Option<F::Output>>
pub fn spawn<F, R>(&self, future: F) -> JoinHandle<Option<F::Output>>
Spawn a task within the scope.
This function is the primary way to introduce concurrency within a Scope.
The spawned task will be cancelled automatically when the Scope is dropped
or when Scope::cancel() is called.
§When to use spawn
Use spawn when you need to react to the outcome of the spawned task.
It returns a JoinHandle<Option<Output>>, allowing you to .await the
result. The Option will be:
Some(value)if the future completes successfully.Noneif the future is cancelled before completion.
If you only need to run a side-effect on completion or cancellation (like decrementing a counter), consider using Scope::spawn_with_hooks for a more direct API.
use scope_spawn::scope::Scope;
use std::time::Duration;
use tokio::time::sleep;
#[tokio::main]
async fn main() {
let scope = Scope::new();
let handle = scope.spawn(async {
// Simulate some work
sleep(Duration::from_millis(10)).await;
"Hello from a spawned task!"
});
let result = handle.await.unwrap();
assert!(result.is_some());
assert_eq!(result.unwrap(), "Hello from a spawned task!");
// scope is dropped here, and any remaining tasks are cancelled.
}Sourcepub fn spawn_with_hooks<F, C, D, R>(
&self,
future: F,
on_completion: C,
on_cancellation: D,
)
pub fn spawn_with_hooks<F, C, D, R>( &self, future: F, on_completion: C, on_cancellation: D, )
Spawn a “fire-and-forget” task with completion and cancellation hooks.
This function is useful when you need to execute a side-effect based on the task’s outcome, but do not need to handle its return value directly.
- The
on_completionclosure runs if the task finishes successfully. - The
on_cancellationclosure runs if the task is cancelled.
§When to use spawn_with_hooks
This method is ideal for managing resources, such as semaphores or counters, that are tied to the lifecycle of a task. For example, you might decrement an “in-flight requests” counter in both hooks to ensure it’s always accurate, regardless of how the task terminates.
If you need to await the task’s result, use Scope::spawn instead.
use scope_spawn::scope::Scope;
use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
#[tokio::main]
async fn main() {
let scope = Scope::new();
let completed_count = Arc::new(AtomicUsize::new(0));
let count_clone = completed_count.clone();
scope.spawn_with_hooks(
async { /* ... */ },
move || { count_clone.fetch_add(1, Ordering::SeqCst); },
|| { /* handle cancellation */ }
);
// Give the task time to complete.
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
assert_eq!(completed_count.load(Ordering::SeqCst), 1);
// scope is dropped here, and spawned tasks are cancelled.
}