use coerce::actor::context::ActorContext; use coerce::actor::message::{Handler, Message}; use coerce::actor::scheduler::timer::{Timer, TimerTick}; use coerce::actor::system::ActorSystem; use coerce::actor::Actor; use std::time::{Duration, Instant}; pub mod util; #[macro_use] extern crate serde; #[macro_use] extern crate async_trait; #[derive(Clone)] pub struct TestTimer {} struct TimerActor { ticks: Vec, } impl Message for TestTimer { type Result = (); } impl TimerTick for TestTimer {} impl Actor for TimerActor {} #[async_trait] impl Handler for TimerActor { async fn handle(&mut self, _message: TestTimer, _ctx: &mut ActorContext) { self.ticks.push(Instant::now()); } } #[ignore] #[tokio::test] pub async fn test_timer() { util::create_trace_logger(); let actor_ref = ActorSystem::new() .new_tracked_actor(TimerActor { ticks: vec![] }) .await .unwrap(); const TICK_DURATION: u64 = 1; let start = Instant::now(); let timer = Timer::start( actor_ref.clone(), Duration::from_secs(TICK_DURATION), TestTimer {}, ); tokio::time::sleep(Duration::from_secs(5)).await; timer.stop(); let ticks_after_stopping = actor_ref.exec(|a| a.ticks.clone()).await.unwrap(); tokio::time::sleep(Duration::from_secs(2)).await; let ticks_after_stopping_and_waiting = actor_ref.exec(|a| a.ticks.len()).await.unwrap(); let mut previous_tick = None; for tick in &ticks_after_stopping { if let Some(previous_tick) = previous_tick { tracing::info!("{}", tick.duration_since(previous_tick).as_secs()); assert!(tick.duration_since(previous_tick).as_secs() >= TICK_DURATION); } else { previous_tick = Some(*tick); tracing::info!("{}", tick.duration_since(start).as_secs()); assert!(tick.duration_since(start).as_secs() >= TICK_DURATION); } } assert_eq!(ticks_after_stopping.len(), ticks_after_stopping_and_waiting); }