use std::any::Any;
use std::sync::Arc;
use async_trait::async_trait;
use crate::actor::actor::actor_inner_error::ActorInnerError;
use crate::actor::actor::pid::ExtendedPid;
use crate::actor::actor::restart_statistics::RestartStatistics;
use crate::actor::actor_system::ActorSystem;
use crate::actor::message::message_handle::MessageHandle;
use crate::actor::supervisor::supervisor_strategy::{SupervisorHandle, SupervisorStrategy};
#[derive(Debug, Clone)]
pub struct SupervisorStrategyHandle(Arc<dyn SupervisorStrategy>);
impl PartialEq for SupervisorStrategyHandle {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.0, &other.0)
}
}
impl Eq for SupervisorStrategyHandle {}
impl std::hash::Hash for SupervisorStrategyHandle {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
(self.0.as_ref() as *const dyn SupervisorStrategy).hash(state);
}
}
impl SupervisorStrategyHandle {
pub fn new_arc(s: Arc<dyn SupervisorStrategy>) -> Self {
if s.as_any().downcast_ref::<SupervisorStrategyHandle>().is_some() {
panic!("SupervisorStrategyHandle can't be used as a strategy, {:?}", s)
}
Self(s)
}
pub fn new(s: impl SupervisorStrategy + 'static) -> Self {
if s.as_any().downcast_ref::<SupervisorStrategyHandle>().is_some() {
panic!("SupervisorStrategyHandle can't be used as a strategy, {:?}", s)
}
Self(Arc::new(s))
}
}
#[async_trait]
impl SupervisorStrategy for SupervisorStrategyHandle {
async fn handle_child_failure(
&self,
actor_system: &ActorSystem,
supervisor: SupervisorHandle,
child: ExtendedPid,
rs: RestartStatistics,
reason: ActorInnerError,
message_handle: MessageHandle,
) {
self
.0
.handle_child_failure(actor_system, supervisor, child, rs, reason, message_handle)
.await
}
fn as_any(&self) -> &dyn Any {
self
}
}