use crate::actors::actor::Actor;
use crate::actors::director::{ActorsDirector, ActorsDirectorConfiguration};
use crate::actors::handle::Receive;
use crate::actors::handle::Respond;
use crate::actors::proxy::ActorReport;
use crate::services::director::ServicesDirector;
use crate::services::handle::Listen;
use crate::services::handle::Serve;
use crate::services::service::Service;
use async_std::{sync::Arc, task::block_on};
use futures::join;
use std::any::TypeId;
use std::fmt::Debug;
#[derive(Debug)]
pub(crate) struct SystemDirector {
actors_director: Arc<ActorsDirector>,
services_director: Arc<ServicesDirector>,
}
impl SystemDirector {
pub(crate) fn new() -> SystemDirector {
let mut actors_director = Arc::new(ActorsDirector::new(ActorsDirectorConfiguration {
innactivity_seconds_until_actor_end: std::time::Duration::from_secs(300),
}));
let mut services_director = Arc::new(ServicesDirector::new());
let system = SystemDirector {
actors_director: actors_director.clone(),
services_director: services_director.clone(),
};
let system_to_return = system.clone();
block_on(async move {
Arc::make_mut(&mut actors_director)
.set_system(system.clone())
.await;
Arc::make_mut(&mut services_director)
.set_system(system.clone())
.await;
});
system_to_return
}
pub async fn send_to_actor<A: Actor + Receive<M>, M: Debug + Send + 'static>(
&self,
actor_id: A::Id,
message: M,
) {
self.actors_director.send::<A, M>(actor_id, message).await
}
pub async fn schedule_send_to_actor<A: Actor + Receive<M>, M: Debug + Send + 'static>(
&self,
actor_id: A::Id,
duration: std::time::Duration,
message: M,
) {
async_std::task::sleep(duration).await;
self.actors_director.send::<A, M>(actor_id, message).await
}
pub async fn send_to_all_actors<A: Actor + Receive<M>, M: Debug + Send + 'static>(
&self,
message: M,
) {
self.actors_director.send_to_all::<A, M>(message).await
}
pub async fn schedule_send_to_all_actors<A: Actor + Receive<M>, M: Debug + Send + 'static>(
&self,
duration: std::time::Duration,
message: M,
) {
async_std::task::sleep(duration).await;
self.actors_director.send_to_all::<A, M>(message).await
}
pub async fn call_actor<A: Actor + Respond<M>, M: Debug + Send + 'static>(
&self,
actor_id: A::Id,
message: M,
) -> Result<<A as Respond<M>>::Response, &str> {
self.actors_director.call::<A, M>(actor_id, message).await
}
pub async fn send_to_service<S: Service + Listen<M>, M: Debug + Send + 'static>(
&self,
message: M,
) {
self.services_director.send::<S, M>(message).await
}
pub async fn call_service<S: Service + Serve<M>, M: Debug + Send + 'static>(
&self,
message: M,
) -> Result<<S as Serve<M>>::Response, &str> {
self.services_director.call::<S, M>(message).await
}
pub(crate) async fn preload_service<S: Service>(&self) {
self.services_director.preload::<S>().await;
}
pub(crate) async fn wait_until_stopped(&self) {
let actors_future = self.actors_director.wait_until_stopped();
let services_future = self.services_director.wait_until_stopped();
join!(actors_future, services_future);
}
pub(crate) async fn stop(&self) {
join!(self.actors_director.stop(), self.services_director.stop());
}
pub(crate) fn get_statistics(&self) -> Vec<(TypeId, Vec<ActorReport>)> {
self.actors_director.get_statistics()
}
pub(crate) async fn publish<M: Send + Clone + 'static>(&self, message: M) {
self.services_director.publish(message).await
}
}
impl Clone for SystemDirector {
fn clone(&self) -> Self {
SystemDirector {
actors_director: self.actors_director.clone(),
services_director: self.services_director.clone(),
}
}
}