I'm trying to use the actors as documented in the actix documentation. But even the doc example is not working for me. I tried the following code which compiles but does not print the message "Received fibo message"
use actix::prelude::*;
// #[derive(Message)]
// #[rtype(Result = "Result<u64, ()>")]
// struct Fibonacci(pub u32);
struct Fibonacci(pub u32);
impl Message for Fibonacci {
type Result = Result<u64, ()>;
}
struct SyncActor;
impl Actor for SyncActor {
// It's important to note that you use "SyncContext" here instead of "Context".
type Context = SyncContext<Self>;
}
impl Handler<Fibonacci> for SyncActor {
type Result = Result<u64, ()>;
fn handle(&mut self, msg: Fibonacci, _: &mut Self::Context) -> Self::Result {
println!("Received fibo message");
if msg.0 == 0 {
Err(())
} else if msg.0 == 1 {
Ok(1)
} else {
let mut i = 0;
let mut sum = 0;
let mut last = 0;
let mut curr = 1;
while i < msg.0 - 1 {
sum = last + curr;
last = curr;
curr = sum;
i += 1;
}
Ok(sum)
}
}
}
fn main() {
System::new().block_on(async {
// Start the SyncArbiter with 2 threads, and receive the address of the Actor pool.
let addr = SyncArbiter::start(2, || SyncActor);
// send 5 messages
for n in 5..10 {
// As there are 2 threads, there are at least 2 messages always being processed
// concurrently by the SyncActor.
println!("Sending fibo message");
addr.do_send(Fibonacci(n));
}
});
}
This program displays 5 times :
Sending fibo message
Two remarks, first I'm unable to use the macro rtype, I use to implement Message myself. And then the line addr.do_send(Fibonacci(n))
seems to not send anything to my actor. However if I use addr.send(Fibonacci(n)).await;
my message get sent and received on the actor side. But since I'm awaiting the send function it processes the message synchronously instead of using the 2 threads I have defined theoretically.
I also tried to wait with a thread::sleep after my main loop but the messages were not arriving either.
I might be misunderstanding something but it seems strange to me.
Cargo.toml file :
[dependencies]
actix = "0.11.1"
actix-rt = "2.2.0"
I finally managed to make it works, though I can't understand exactly why. Simply using tokio to wait for a ctrl-C made it possible for me to call do_send/try_send and work in parallel.