use std::ops::ControlFlow;
use std::time::Duration;
use tokio::time::Instant;
use xtra::prelude::*;
#[derive(Default, xtra::Actor)]
struct Counter {
count: usize,
}
struct Inc;
impl Handler<Inc> for Counter {
type Return = ();
async fn handle(&mut self, _inc: Inc, _ctx: &mut Context<Self>) {
tokio::time::sleep(Duration::from_millis(50)).await;
self.count += 1;
}
}
#[tokio::main]
async fn main() {
let (address, mailbox) = Mailbox::unbounded();
let mut actor = Counter::default();
tokio::spawn(async move {
if let Err(()) = actor.started(&mailbox).await {
return;
}
loop {
let start = Instant::now();
let msg = mailbox.next().await;
println!("Got message in {}us", start.elapsed().as_micros());
let before = actor.count;
let start = Instant::now();
let ctrl = msg.dispatch_to(&mut actor).await;
if let ControlFlow::Break(_) = ctrl {
println!("Goodbye!");
break;
}
println!(
"Count changed from {} to {} in {:.2}ms\n",
before,
actor.count,
start.elapsed().as_secs_f32() * 1000.0
);
}
});
for _ in 0..100 {
address
.send(Inc)
.await
.expect("Counter should not be dropped");
}
drop(address);
tokio::time::sleep(Duration::from_secs(1)).await;
}