use anyhow::Result;
use rsactor::{message_handlers, Actor, ActorRef, ActorWeak};
use tokio::time::{interval, Duration};
use tracing::info;
struct Increment; struct Decrement;
struct MyActor {
count: u32, start_up: std::time::Instant, tick_300ms: tokio::time::Interval, tick_1s: tokio::time::Interval, }
impl Actor for MyActor {
type Args = Self;
type Error = anyhow::Error;
async fn on_start(args: Self::Args, _actor_ref: &ActorRef<Self>) -> Result<Self, Self::Error> {
info!("MyActor started. Initial count: {}.", args.count);
Ok(args)
}
async fn on_run(&mut self, _actor_ref: &ActorWeak<Self>) -> Result<bool, Self::Error> {
tokio::select! {
_ = self.tick_300ms.tick() => {
println!("300ms tick. Elapsed: {:?}",
self.start_up.elapsed()); }
_ = self.tick_1s.tick() => {
println!("1s tick. Elapsed: {:?} ",
self.start_up.elapsed()); }
}
Ok(true) }
}
struct DummyMessage;
#[message_handlers]
impl MyActor {
#[handler]
async fn handle_increment(&mut self, _msg: Increment, _: &ActorRef<Self>) -> u32 {
self.count += 1;
println!("MyActor handled Increment. Count is now {}.", self.count);
self.count
}
#[handler]
async fn handle_decrement(&mut self, _msg: Decrement, _: &ActorRef<Self>) -> u32 {
self.count -= 1;
println!("MyActor handled Decrement. Count is now {}.", self.count);
self.count
}
#[handler]
async fn handle_dummy_message(&mut self, _msg: DummyMessage, _: &ActorRef<Self>) -> u32 {
println!("MyActor handled DummyMessage. Count is now {}.", self.count);
self.count
}
}
#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::DEBUG)
.with_target(false)
.init();
println!("Spawning MyActor...");
let my_actor = MyActor {
count: 100,
start_up: std::time::Instant::now(),
tick_300ms: interval(Duration::from_millis(300)),
tick_1s: interval(Duration::from_secs(1)),
};
let (actor_ref, join_handle) = rsactor::spawn::<MyActor>(my_actor);
tokio::time::sleep(Duration::from_millis(700)).await;
println!("Sending Increment message...");
let count_after_inc: u32 = actor_ref.ask(Increment).await?;
println!("Reply after Increment: {count_after_inc}");
println!("Sending Decrement message...");
let count_after_dec: u32 = actor_ref.ask(Decrement).await?;
println!("Reply after Decrement: {count_after_dec}");
println!("Sending Increment message again...");
let count_after_inc_2: u32 = actor_ref.ask(Increment).await?;
println!("Reply after Increment again: {count_after_inc_2}");
tokio::time::sleep(Duration::from_millis(700)).await;
println!("Sending StopGracefully message to actor.",);
actor_ref.stop().await?;
println!("Waiting for actor to stop...");
let result = join_handle.await?;
match result {
rsactor::ActorResult::Completed { actor, killed } => {
println!(
"Actor stopped. Final count: {}. Killed: {}",
actor.count, killed
);
}
rsactor::ActorResult::Failed {
actor,
error,
phase,
killed,
} => {
println!(
"Actor stop failed: {}. Phase: {}, Killed: {}. Final count: {}",
error,
phase,
killed,
actor.as_ref().map(|a| a.count).unwrap_or(0)
);
}
}
println!("Main function finished.");
Ok(())
}