use crate::message::create_init_lifecycle;
use crate::message::Message;
use crate::message::MessageEnvelope;
use async_trait::async_trait;
use tokio::sync::mpsc;
use tokio::sync::oneshot;
#[async_trait]
pub trait Actor {
async fn handle_envelope(&mut self, envelope: MessageEnvelope);
async fn stop(&mut self);
}
pub struct ActorHandle {
#[doc(hidden)]
pub sender: mpsc::Sender<MessageEnvelope>,
}
impl<'a> ActorHandle {
#[doc(hidden)]
pub async fn send(&self, envelope: MessageEnvelope) {
self.sender
.send(envelope)
.await
.expect("other actor cannot receive");
}
pub async fn tell(&self, message: Message) {
let envelope = MessageEnvelope {
message,
respond_to: None,
..Default::default()
};
self.send(envelope).await;
}
pub async fn ask(&self, message: Message) -> Message {
let (send, recv) = oneshot::channel();
let envelope = MessageEnvelope {
message,
respond_to: Some(send),
..Default::default()
};
self.send(envelope).await;
recv.await.expect("other actor cannot reply")
}
pub async fn integrate(&self, message: Message, path: String, helper: &ActorHandle) -> Message {
let (send, recv) = oneshot::channel();
let (init_cmd, load_cmd) = create_init_lifecycle(message.clone(), path, 8, Some(send));
helper.send(load_cmd).await;
self.send(init_cmd).await;
recv.await.expect("other actor cannot reply")
}
}
impl ActorHandle {
#[doc(hidden)]
pub fn new(sender: mpsc::Sender<MessageEnvelope>) -> Self {
Self { sender }
}
}