use std::time::Duration;
use simpl_actor::*;
pub struct CounterActor {
count: i64,
}
impl Actor for CounterActor {
type Ref = CounterActorRef;
async fn on_start(&mut self) -> Result<(), BoxError> {
println!("starting actor");
Ok(())
}
async fn on_panic(&mut self, _err: PanicErr) -> Result<Option<ActorStopReason>, BoxError> {
println!("actor panicked but will continue running");
Ok(None)
}
async fn on_stop(self, reason: ActorStopReason) -> Result<(), BoxError> {
println!("stopping actor because {reason}",);
Ok(())
}
}
#[actor]
impl CounterActor {
pub fn new() -> Self {
CounterActor { count: 0 }
}
#[message]
pub fn inc(&mut self, amount: i64) {
self.count += amount;
}
#[message(infallible)]
pub fn count(&self) -> i64 {
self.count
}
#[message]
pub fn error(&self) -> Result<(), std::io::Error> {
Err(std::io::Error::new(std::io::ErrorKind::Other, "oh no!"))
}
#[message]
pub async fn sleep(&self) {
tokio::time::sleep(Duration::from_millis(100)).await;
}
#[message]
pub async fn inc_myself(&self) -> Result<(), SendError<i64>> {
self.actor_ref().inc_async(1)
}
#[message]
pub fn force_panic(&self) {
panic!("forced panic, don't worry this is correct and the actor will be restarted")
}
}
#[tokio::main(flavor = "current_thread")]
async fn main() {
let counter = CounterActor::new();
let actor = counter.spawn();
assert_eq!(actor.inc(2).await, Ok(()));
assert_eq!(actor.count().await, Ok(2));
assert_eq!(actor.sleep_async(), Ok(()));
assert_eq!(actor.force_panic().await, Err(SendError::ActorStopped));
assert_eq!(actor.error_async(), Ok(()));
assert_eq!(actor.inc(1).await, Ok(()));
assert_eq!(actor.count().await, Ok(3));
actor.kill();
actor.wait_for_stop().await;
assert_eq!(actor.inc(1).await, Err(SendError::ActorNotRunning(1)));
}