Mostly interested in what am I missing in my actix mental model, thank you in advance! Here is a pretty rudimentary actix example with ping pong messages and corresponding responses:
#[derive(Message)]
#[rtype(result = "Responses")]
enum Messages {Ping,Pong}
#[derive(Debug)]
enum Responses {GotPing,GotPong}
impl<A, M> MessageResponse<A, M> for Responses
where
A: Actor,
M: Message<Result = Responses>
{
fn handle(self, _ctx: &mut A::Context, tx: Option<OneshotSender<M::Result>>) {
if let Some(tx) = tx {tx.send(self);}
}
}
And here is main:
#[actix_rt::main]
pub async fn main() {
let addr = ActorQuox.start();
let pongfut_async = addr.send(Messages::Pong).await;
pongfut_async.map_or(Responses::GotPong, |res| {
println!("Got result: {:?}", res);
res
});
let ping = addr.do_send(Messages::Ping);
}
Whereas i would expect the output to be:
Got message
Got result: GotPong
Got message
It is actually:
Got message
Got result: GotPong
I'm not sure how to reason about this given that i think that the handler impl Handler<Messages> for ActorQuox
i supposed to fire on all three of do_send
, send
and try_send
given that they all do tx.send(self)
in their implementations on Addr
and the difference is only in the return signatures. I'm obviously wrong about this or something else.
Because you can't .await
a do_send()
, the execution continues and will exit main()
. This will cause the async runtime created by #[actix_rt::main]
to shut down and will not complete any pending tasks.
You can add a sleep()
call and you'd probably see it.