coerce 0.8.11

Async actor runtime and distributed systems framework
Documentation
use crate::util::TestActor;
use async_trait::async_trait;
use coerce::actor::context::ActorContext;
use coerce::actor::message::Handler;
use coerce::actor::system::ActorSystem;
use coerce::actor::watch::{ActorTerminated, ActorWatch};
use coerce::actor::{Actor, ActorId, CoreActorRef, IntoActor, LocalActorRef};
use tokio::sync::oneshot;
use tokio::sync::oneshot::Sender;

pub mod util;

pub struct Watchdog {
    target: LocalActorRef<TestActor>,
    on_actor_terminated: Option<Sender<ActorTerminated>>,
}

#[async_trait]
impl Actor for Watchdog {
    async fn started(&mut self, ctx: &mut ActorContext) {
        self.watch(&self.target, ctx);
    }
}

#[async_trait]
impl Handler<ActorTerminated> for Watchdog {
    async fn handle(&mut self, message: ActorTerminated, _ctx: &mut ActorContext) {
        if let Some(on_actor_terminated) = self.on_actor_terminated.take() {
            let _ = on_actor_terminated.send(message);
        }
    }
}

#[tokio::test]
pub async fn test_actor_watch_notifications() {
    let system = ActorSystem::new();
    let actor = TestActor::new()
        .into_actor(Option::<ActorId>::None, &system)
        .await
        .unwrap();
    let (tx, rx) = oneshot::channel();
    let _watchdog = Watchdog {
        target: actor.clone(),
        on_actor_terminated: Some(tx),
    }
    .into_actor(Option::<ActorId>::None, &system)
    .await
    .unwrap();

    let _ = actor.notify_stop();
    let actor_terminated = rx.await.unwrap();
    let terminated_actor = actor_terminated.actor_ref();

    assert_eq!(terminated_actor.actor_id(), actor.actor_id());
    assert_eq!(terminated_actor.is_valid(), false);
}