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 for Counter { type Return = (); async fn handle(&mut self, _inc: Inc, _ctx: &mut Context) { // Do some "work" 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"); } // Wait for the actor to stop drop(address); tokio::time::sleep(Duration::from_secs(1)).await; }