use std::fmt::Debug; use std::future::Future;
use acton_ern::Ern;
use async_trait::async_trait;
use dashmap::DashMap;
use tokio_util::task::TaskTracker;
use tracing::{instrument, trace};
use crate::common::{ActorHandle, OutboundEnvelope}; use crate::message::{BrokerRequest, MessageAddress}; use crate::traits::acton_message::ActonMessage;
use crate::traits::request::Request;
#[async_trait]
pub trait ActorHandleInterface: Send + Sync + Debug + Clone + 'static {
fn reply_address(&self) -> MessageAddress;
fn create_envelope(&self, recipient_address: Option<MessageAddress>) -> OutboundEnvelope;
fn children(&self) -> &DashMap<String, ActorHandle>;
fn find_child(&self, id: &Ern) -> Option<ActorHandle>;
fn tracker(&self) -> TaskTracker;
fn id(&self) -> Ern;
fn name(&self) -> String;
fn clone_ref(&self) -> ActorHandle;
#[instrument(skip(self, message), fields(message_type = std::any::type_name_of_val(&message)))]
fn send(&self, message: impl ActonMessage) -> impl Future<Output = ()> + Send + Sync + '_ {
async move {
let envelope = self.create_envelope(Some(self.reply_address()));
trace!(sender = %self.id(), recipient = %self.id(), "Default send implementation");
envelope.send(message).await;
}
}
fn ask<R: Request>(
&self,
request: R,
) -> impl Future<Output = Result<R::Response, crate::common::AskError>> + Send + '_ {
self.ask_with_timeout(request, crate::common::DEFAULT_ASK_TIMEOUT)
}
#[instrument(skip(self, request), fields(request_type = std::any::type_name::<R>()))]
fn ask_with_timeout<R: Request>(
&self,
request: R,
timeout: std::time::Duration,
) -> impl Future<Output = Result<R::Response, crate::common::AskError>> + Send + '_ {
let cancellation_token = self.create_envelope(None).cancellation_token;
let recipient = self.reply_address();
trace!(recipient = %self.id(), "Asking actor and awaiting its reply");
crate::common::ask::send_request(recipient, cancellation_token, request, timeout)
}
fn send_sync(&self, message: impl ActonMessage, recipient: &ActorHandle) -> anyhow::Result<()>
where
Self: Sized, {
trace!(sender = %self.id(), recipient = %recipient.id(), "Sending message synchronously");
let envelope = self.create_envelope(Some(recipient.reply_address()));
envelope.reply(BrokerRequest::new(message))?; Ok(())
}
fn stop(&self) -> impl Future<Output = anyhow::Result<()>> + Send + Sync + '_;
#[cfg(feature = "ipc")]
fn send_boxed(
&self,
message: Box<dyn ActonMessage + Send + Sync>,
) -> impl Future<Output = anyhow::Result<()>> + Send + Sync + '_;
#[cfg(feature = "ipc")]
fn send_boxed_with_reply_to(
&self,
message: Box<dyn ActonMessage + Send + Sync>,
reply_to: MessageAddress,
) -> impl Future<Output = anyhow::Result<()>> + Send + Sync + '_;
#[cfg(feature = "ipc")]
fn try_send_boxed(
&self,
message: Box<dyn ActonMessage + Send + Sync>,
) -> Result<(), crate::common::ipc::IpcError>;
#[cfg(feature = "ipc")]
fn try_send_boxed_with_reply_to(
&self,
message: Box<dyn ActonMessage + Send + Sync>,
reply_to: MessageAddress,
) -> Result<(), crate::common::ipc::IpcError>;
}