use std::any::Any;
use std::fmt::Debug;
use crate::message::BoxedDowncastErr;
use crate::ActorProcessingErr;
use crate::State;
pub struct BoxedState {
pub msg: Option<Box<dyn Any + Send>>,
}
impl Debug for BoxedState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BoxedState").finish()
}
}
impl BoxedState {
pub fn new<T>(msg: T) -> Self
where
T: State,
{
Self {
msg: Some(Box::new(msg)),
}
}
pub fn take<T>(&mut self) -> Result<T, BoxedDowncastErr>
where
T: State,
{
match self.msg.take() {
Some(m) => {
if m.is::<T>() {
Ok(*m.downcast::<T>().unwrap())
} else {
Err(BoxedDowncastErr)
}
}
None => Err(BoxedDowncastErr),
}
}
}
#[derive(Debug)]
pub enum StopMessage {
Stop,
Reason(String),
}
impl std::fmt::Display for StopMessage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Stop => write!(f, "Stop"),
Self::Reason(reason) => write!(f, "Stop (reason = {reason})"),
}
}
}
#[cfg(feature = "cluster")]
impl crate::Message for StopMessage {}
pub enum SupervisionEvent {
ActorStarted(super::actor_cell::ActorCell),
ActorTerminated(
super::actor_cell::ActorCell,
Option<BoxedState>,
Option<String>,
),
ActorFailed(super::actor_cell::ActorCell, ActorProcessingErr),
ProcessGroupChanged(crate::pg::GroupChangeMessage),
#[cfg(feature = "cluster")]
PidLifecycleEvent(crate::registry::PidLifecycleEvent),
}
#[cfg(feature = "cluster")]
impl crate::Message for SupervisionEvent {}
impl SupervisionEvent {
pub fn actor_cell(&self) -> Option<&super::actor_cell::ActorCell> {
match self {
Self::ActorStarted(who)
| Self::ActorFailed(who, _)
| Self::ActorTerminated(who, _, _) => Some(who),
_ => None,
}
}
pub fn actor_id(&self) -> Option<super::actor_id::ActorId> {
self.actor_cell().map(|cell| cell.get_id())
}
#[cfg(feature = "monitors")]
pub(crate) fn clone_no_data(&self) -> Self {
match self {
Self::ActorStarted(who) => Self::ActorStarted(who.clone()),
Self::ActorFailed(who, what) => {
Self::ActorFailed(who.clone(), From::from(format!("{what}")))
}
Self::ProcessGroupChanged(what) => Self::ProcessGroupChanged(what.clone()),
Self::ActorTerminated(who, _state, msg) => {
Self::ActorTerminated(who.clone(), None, msg.as_ref().cloned())
}
#[cfg(feature = "cluster")]
Self::PidLifecycleEvent(evt) => Self::PidLifecycleEvent(evt.clone()),
}
}
}
impl Debug for SupervisionEvent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Supervision event: {self}")
}
}
impl std::fmt::Display for SupervisionEvent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SupervisionEvent::ActorStarted(actor) => {
write!(f, "Started actor {actor:?}")
}
SupervisionEvent::ActorTerminated(actor, _, reason) => {
if let Some(r) = reason {
write!(f, "Stopped actor {actor:?} (reason = {r})")
} else {
write!(f, "Stopped actor {actor:?}")
}
}
SupervisionEvent::ActorFailed(actor, panic_msg) => {
write!(f, "Actor panicked {actor:?} - {panic_msg}")
}
SupervisionEvent::ProcessGroupChanged(change) => {
write!(
f,
"Process group {} in scope {} changed",
change.get_group(),
change.get_scope()
)
}
#[cfg(feature = "cluster")]
SupervisionEvent::PidLifecycleEvent(change) => {
write!(f, "PID lifecycle event {change:?}")
}
}
}
}
#[derive(Clone, Debug)]
pub enum Signal {
Kill,
}
impl std::fmt::Display for Signal {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Kill => {
write!(f, "killed")
}
}
}
}