use anyhow::Result;
use rsactor::{message_handlers, spawn_with_options, Actor, ActorRef, SpawnOptions};
use std::time::Duration;
#[derive(Debug)]
struct WorkerActor {
jobs_done: u32,
paused: bool,
}
#[derive(Debug)]
struct ProcessJob {
id: u32,
}
#[derive(Debug)]
struct HealthCheck;
#[derive(Debug)]
struct HealthSnapshot {
jobs_done: u32,
paused: bool,
}
#[derive(Debug)]
struct PauseProcessing;
#[derive(Debug)]
struct ResumeProcessing;
impl Actor for WorkerActor {
type Args = ();
type Error = anyhow::Error;
async fn on_start(_: (), _: &ActorRef<Self>) -> Result<Self> {
Ok(WorkerActor {
jobs_done: 0,
paused: false,
})
}
}
#[message_handlers]
impl WorkerActor {
#[handler]
async fn handle_job(&mut self, msg: ProcessJob, _: &ActorRef<Self>) {
if self.paused {
println!("[worker] paused — skipping job #{}", msg.id);
return;
}
println!("[worker] starting job #{}", msg.id);
tokio::time::sleep(Duration::from_millis(150)).await;
self.jobs_done += 1;
println!("[worker] finished job #{}", msg.id);
}
#[handler]
async fn handle_health(&mut self, _: HealthCheck, _: &ActorRef<Self>) -> HealthSnapshot {
HealthSnapshot {
jobs_done: self.jobs_done,
paused: self.paused,
}
}
#[handler]
async fn handle_pause(&mut self, _: PauseProcessing, _: &ActorRef<Self>) {
println!("[worker] *** PAUSE signal received ***");
self.paused = true;
}
#[handler]
async fn handle_resume(&mut self, _: ResumeProcessing, _: &ActorRef<Self>) {
println!("[worker] *** RESUME signal received ***");
self.paused = false;
}
}
#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::WARN)
.with_target(false)
.init();
println!("=== Priority Channel Demo ===\n");
let opts = SpawnOptions::new().mailbox_capacity(8).with_priority();
let (actor, join) = spawn_with_options::<WorkerActor>((), opts);
assert!(actor.has_priority_channel());
for id in 1..=5 {
actor.tell(ProcessJob { id }).await?;
}
tokio::time::sleep(Duration::from_millis(50)).await;
let snap = actor
.ask_priority(HealthCheck, Duration::from_secs(1))
.await?;
println!(
"[main] health snapshot mid-flight: jobs_done={}, paused={}",
snap.jobs_done, snap.paused
);
actor
.tell_priority(PauseProcessing, Duration::from_secs(1))
.await?;
tokio::time::sleep(Duration::from_millis(400)).await;
let snap = actor
.ask_priority(HealthCheck, Duration::from_secs(1))
.await?;
println!(
"[main] health snapshot after pause: jobs_done={}, paused={}",
snap.jobs_done, snap.paused
);
actor
.tell_priority(ResumeProcessing, Duration::from_secs(1))
.await?;
actor.stop().await?;
let result = join.await?;
if let Some(final_state) = result.actor() {
println!(
"\n[main] worker stopped. final jobs_done={}, paused={}",
final_state.jobs_done, final_state.paused
);
}
println!("\n=== Demo Complete ===");
Ok(())
}