select

Function select 

Source
pub async fn select<A, F, R>(
    mailbox: &Mailbox<A>,
    actor: &mut A,
    fut: F,
) -> Either<R, F>
where F: Future<Output = R> + Unpin, A: Actor,
Expand description

Handle any incoming messages for the actor while running a given future. This is similar to join, but will exit if the actor is stopped, returning the future. Returns Ok with the result of the future if it was successfully completed, or Err with the future if the actor was stopped before it could complete. It is analagous to futures::select.

ยงExample

use futures_util::future::Either;

struct Stop;
struct Selecting;

impl Handler<Stop> for MyActor {
    type Return = ();

    async fn handle(&mut self, _msg: Stop, ctx: &mut Context<Self>) {
        ctx.stop_self();
    }
}

impl Handler<Selecting> for MyActor {
    type Return = bool;

    async fn handle(&mut self, _msg: Selecting, ctx: &mut Context<Self>) -> bool {
        // Actor is still running, so this will return Either::Left
        match xtra::select(ctx.mailbox(), self, future::ready(1)).await {
            Either::Left(ans) => println!("Answer is: {}", ans),
            Either::Right(_) => panic!("How did we get here?"),
        };

        let addr = ctx.mailbox().address();
        let select = xtra::select(ctx.mailbox(), self, future::pending::<()>());
        let _ = addr.send(Stop).detach().await;

        // Actor is stopping, so this will return Err, even though the future will
        // usually never complete.
        matches!(select.await, Either::Right(_))
    }
}

smol::block_on(async {
    let addr = xtra::spawn_smol(MyActor, Mailbox::unbounded());
    assert!(addr.is_connected());
    assert_eq!(addr.send(Selecting).await, Ok(true)); // Assert that the select did end early
})