use std::time::Duration; use tokio::{task, time::sleep}; use tractor::prelude::*; struct Accumulator { sum: usize, } enum AccumulatorMsg { Add { a: usize }, Sub { a: usize }, } impl Actor for Accumulator { type Msg = AccumulatorMsg; } impl ActorBehavior for Accumulator { fn handle(&mut self, msg: AccumulatorMsg, _: &Context) { match msg { AccumulatorMsg::Add { a } => self.sum += a, AccumulatorMsg::Sub { a } => self.sum -= a, } } } impl ActorHooks for Accumulator { fn stopped(&mut self) { println!("Final sum: {}", self.sum); } } #[derive(Clone)] struct Accum(Addr); impl Accum { fn overloaded(&self) -> bool { self.0.len() > 1000 } fn add(&self, a: usize) { self.0.send(AccumulatorMsg::Add { a }); } fn sub(&self, a: usize) { self.0.send(AccumulatorMsg::Sub { a }); } } fn run() { let actor = Accumulator { sum: 0 }; let addr = Accum(actor.start()); let _feeder = task::spawn(async move { for _i in 0..1_000_000_usize { while addr.overloaded() { sleep(Duration::from_millis(1)).await; // println!("Overload"); } addr.add(1); } }); } fn main() { ActorSystem::run_to_completion(run); }