async_scope

Macro async_scope 

Source
macro_rules! async_scope {
    (|$scope:ident| -> $result:ty { $($body:tt)* }) => { ... };
    (|$scope:ident| $body:expr) => { ... };
}
Expand description

Creates an async scope within which you can spawn jobs. This works much like the stdlib’s scope function.

The scope is not considered to be complete until all jobs within the scope have completed. Jobs spawned within the scope can refer to stack variables that are defined outside the scope.

§Cancellable vs infallible scopes

By default, moro scopes support cancellation, which means that you can cancel the entire scope by invoking scope.cancel(v). Cancellable scopes return a Result value whose error type is the type of v. If your scope does not use cancel, you will get compilation errors because the error type cannot be inferred!

To avoid this, use the infallible method on the scope to convert it into a non-cancellable scope:

let scope = moro::async_scope!(|scope| {/* ... */}).await;

§Access to stack variables

Futures spawned inside an async scope can refer to stack variables defined outside the scope:

let r = 22;
let scope = moro::async_scope!(|scope| {
    // OK to refer to `r` here
    scope.spawn(async { r }).await
});
let result = scope.await;
assert_eq!(result, 22);

but when you spawn a future, that future cannot refer to stack variables defined inside the scope (except its own variables, of course):

let scope = moro::async_scope!(|scope| {
    let r = 22;
    // NOT ok to refer to `r` now, because `r`
    // is defined inside the scope
    scope.spawn(async { r }).await
});
let result = scope.await;
assert_eq!(result, 22);

§Examples

§Hello, world

The following scope spawns one concurrent task which iterates over the vector v and sums its values; the [infallible][Scope::infallible] method is used to indicate that the scope is never cancelled:

let v = vec![1, 2, 3, 5];
let scope = moro::async_scope!(|scope| {
    let job = scope.spawn(async {
        let r: i32 = v.iter().sum();
        r
    });
    job.await * 2
});
let result = scope.await;
assert_eq!(result, 22);

§Specifying the result type

You can use the -> notation to specify the type of value returned by the scope. This is useful to guide type inference sometimes:

let scope = moro::async_scope!(|scope| -> Result<(), u32> {
    Err(22) // Ok type would otherwise be unconstrained
});
let result = scope.await;
assert_eq!(result, Err(22));

§More

For more examples, see the examples directory in the repository.