pub async fn select<A, F, R>(
mailbox: &Mailbox<A>,
actor: &mut A,
fut: F,
) -> Either<R, F>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
})