Macro blaze_rs::scope_async

source ·
macro_rules! scope_async {
    ($f:expr) => { ... };
    ($ctx:expr, $f:expr) => { ... };
}
Expand description

Creates a new scope for spawining scoped events.

The scope_async macro allows for the creation of async scopes, returning a Future that completes when all the events spawned inside the scope have completed.

use blaze_rs::{buffer, scope_async, prelude::*};
use futures::future::*;

#[global_context]
static CONTEXT : SimpleContext = SimpleContext::default();

let buffer = buffer![1, 2, 3, 4, 5]?;

let (left, right) = scope_async!(|s| async {
    let left = buffer.read(s, ..2, None)?.join_async()?;
    let right = buffer.read(s, ..2, None)?.join_async()?;
    return tokio::try_join!(left, right);
}).await?;

assert_eq!(left, vec![1, 2]);
assert_eq!(right, vec![3, 4, 5]);

This macro can be called with the same form as scope or local_scope.

use blaze_rs::{scope_async, prelude::*};

#[global_context]
static CONTEXT : SimpleContext = SimpleContext::default();

let ctx = SimpleContext::default()?;
let buffer = Buffer::new_in(ctx, &[1, 2, 3, 4, 5], MemAccess::default(), false)?;

let (left, right) = scope_async!(buffer.context(), |s| async {
    let left = buffer.read(s, ..2, None)?.join_async()?;
    let right = buffer.read(s, ..2, None)?.join_async()?;
    return tokio::try_join!(left, right);
}).await?;

assert_eq!(left, vec![1, 2]);
assert_eq!(right, vec![3, 4, 5]);

Unlike it’s blocking counterpart, scope_async does not ensure that all events inside the future will be ran. Rather, if the future is dropped before completion, it’s destructor will block the current thread until every already-started event has completed, and discarting the remaining uninitialized events.

use blaze_rs::{prelude::*, buffer, scope_async};
use futures::{task::*, future::*};

#[global_context]
static CONTEXT : SimpleContext = SimpleContext::default();

let buffer = buffer![1, 2, 3, 4, 5]?;

let mut scope = Box::pin(scope_async!(|s| async {
    let left = buffer.read(s, ..2, None)?.inspect(|_| println!("Left done!")).join_async()?.await;
    let right = buffer.read(s, ..2, None)?.inspect(|_| println!("Right done!")).join_async()?.await;
    return Ok((left, right));
}));

let mut ctx = std::task::Context::from_waker(noop_waker_ref());
let _ = scope.poll_unpin(&mut ctx)?;
drop(scope); // prints "Left done!", doesn't print "Right done!"