LocalScope

Struct LocalScope 

Source
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>

Source

pub fn new() -> Self

Creates a new spawn scope.

Spawned futures can reference anything before the creation of the scope.

Source

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.

Source

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()));
Source

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);
}));
Source

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);
Source

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);
Source

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]);
Source

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]);

Trait Implementations§

Source§

impl<'sc, T: Debug> Debug for LocalScope<'sc, T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'sc, T> Default for LocalScope<'sc, T>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'sc, T> Drop for LocalScope<'sc, T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<'sc, T = ()> !Freeze for LocalScope<'sc, T>

§

impl<'sc, T = ()> !RefUnwindSafe for LocalScope<'sc, T>

§

impl<'sc, T = ()> !Send for LocalScope<'sc, T>

§

impl<'sc, T = ()> !Sync for LocalScope<'sc, T>

§

impl<'sc, T> Unpin for LocalScope<'sc, T>
where T: Unpin,

§

impl<'sc, T = ()> !UnwindSafe for LocalScope<'sc, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.