pub struct LocalScope<'sc, T = ()> { /* private fields */ }Expand description
A spawn scope that can be used to spawn non-send/sync futures of lifetime 'sc.
Spawned futures are not processed until the scope is polled by awaiting one of the
futures returned by until, until_stalled or until_empty.
Spawned futures can return a result of type T that can be accessed via results or take_results.
§Dropping
If the scope is dropped, all futures that where spawned on it will be dropped as well.
§Examples
use futures_scopes::local::LocalScope;
let some_value = &42;
let mut scope = LocalScope::<usize>::new();
let spawner = scope.spawner();
spawner.spawn_local_scoped(async {
// You can reference `some_value` here
*some_value
}).unwrap();
// Process the scope and wait until all futures have been completed
block_on(scope.until_empty());
// use `scope.results()` to access the results of the spawned futures
assert_eq!(scope.results(), &[42]);Implementations§
Source§impl<'sc, T> LocalScope<'sc, T>
impl<'sc, T> LocalScope<'sc, T>
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new spawn scope.
Spawned futures can reference anything before the creation of the scope.
Sourcepub fn spawner(&self) -> LocalScopeSpawner<'sc, T>
pub fn spawner(&self) -> LocalScopeSpawner<'sc, T>
Get a cloneable spawner that can be used to spawn local futures to this scope.
This spawner can live longer then the scope.
In case a future is spawned after the scope has been dropped, the spawner will return SpawnError::shutdown.
Sourcepub fn cancel(&mut self)
pub fn cancel(&mut self)
Drops all spawned futures and prevents new futures from being spawned.
In case a future is spawned after cancel has been called, the spawner will return SpawnError::shutdown.
§Examples
use futures_scopes::local::LocalScope;
let mut scope = LocalScope::new();
let spawner = scope.spawner();
spawner.spawn_local_scoped(async {
// ...
}).unwrap();
scope.cancel();
let res = spawner.spawn_local_scoped(async { () });
assert!(matches!(res, Err(err) if err.is_shutdown()));Sourcepub fn until<Fut: Future>(&mut self, fut: Fut) -> Until<'_, 'sc, T, Fut> ⓘ
pub fn until<Fut: Future>(&mut self, fut: Fut) -> Until<'_, 'sc, T, Fut> ⓘ
Returns a future that polls the scope until the given future fut is ready.
The returned future will guarantee that at least some progress is made on the futures spawned on this scope, by polling all these futures at least once.
§Examples
let counter = RefCell::new(0);
let mut scope = LocalScope::new();
let spawner = scope.spawner();
for _ in 0..10 {
spawner.spawn_local_scoped(async {
*counter.borrow_mut() += 1;
}).unwrap();
}
// Spawning a never-ready future will not hinder .until from returning
spawner.spawn_local_scoped(pending()).unwrap();
block_on(scope.until(async {
// at least one future has been polled ready
assert!(*counter.borrow() == 10);
}));Sourcepub fn until_stalled(&mut self) -> UntilStalled<'_, 'sc, T> ⓘ
pub fn until_stalled(&mut self) -> UntilStalled<'_, 'sc, T> ⓘ
Returns a future that polls the scope until no further progress can be made, because all spawned futures are pending or the scope is empty.
Guarantees that all spawned futures are polled at least once.
§Examples
let counter = RefCell::new(0);
let (sx, rx) = oneshot::channel();
let mut scope = LocalScope::new();
scope.spawner().spawn_local_scoped(async {
*counter.borrow_mut() += 1;
// wait until the oneshot is ready
rx.await.unwrap();
*counter.borrow_mut() += 1;
}).unwrap();
assert!(*counter.borrow() == 0);
block_on(scope.until_stalled());
// scope is stalled because the future is waiting for rx
assert!(*counter.borrow() == 1);
sx.send(()).unwrap();
block_on(scope.until_stalled());
// scope is empty because the future has finished
assert!(*counter.borrow() == 2);Sourcepub fn until_empty(&mut self) -> UntilEmpty<'_, 'sc, T> ⓘ
pub fn until_empty(&mut self) -> UntilEmpty<'_, 'sc, T> ⓘ
Returns a future that polls the scope until all spawned futures have been polled ready.
§Examples
let counter = RefCell::new(0);
let mut scope = LocalScope::new();
let spawner = scope.spawner();
for _ in 0..10 {
spawner.spawn_local_scoped(async {
*counter.borrow_mut() += 1;
}).unwrap();
}
// Spawning a never-ready future will block .until_empty from ever returning
// spawner.spawn_local_scoped(pending()).unwrap();
block_on(scope.until_empty());
// all futures have been polled ready
assert!(*counter.borrow() == 10);Sourcepub fn results(&self) -> &Vec<T>
pub fn results(&self) -> &Vec<T>
Returns a reference to the results of all futures that have been polled ready until now.
Results are not ordered in any specific way.
To take ownership of the results, use take_results.
§Examples
let mut scope = LocalScope::new();
let spawner = scope.spawner();
for i in 0..5 {
spawner.spawn_local_scoped(async move {
i
}).unwrap();
}
block_on(scope.until_empty());
assert_eq!(scope.results(), &[0, 1, 2, 3, 4]);Sourcepub fn take_results(self) -> Vec<T>
pub fn take_results(self) -> Vec<T>
Returns the results of all futures that have been polled ready until now. This removes the results from the scope. This does not hinder future results from being added to the scope.
Results are not ordered in any specific way.
To not take ownership of the results, use results.
§Examples
let mut scope = LocalScope::new();
let spawner = scope.spawner();
for i in 0..5 {
spawner.spawn_local_scoped(async move {
i
}).unwrap();
}
block_on(scope.until_empty());
assert_eq!(scope.take_results(), vec![0, 1, 2, 3, 4]);