1use std::any::Any;
13use std::fmt::Debug;
14
15use crate::message::BoxedDowncastErr;
16use crate::ActorProcessingErr;
17use crate::State;
18
19pub struct BoxedState {
23 pub msg: Option<Box<dyn Any + Send>>,
25}
26
27impl Debug for BoxedState {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 f.debug_struct("BoxedState").finish()
30 }
31}
32
33impl BoxedState {
34 pub fn new<T>(msg: T) -> Self
36 where
37 T: State,
38 {
39 Self {
40 msg: Some(Box::new(msg)),
41 }
42 }
43
44 pub fn take<T>(&mut self) -> Result<T, BoxedDowncastErr>
47 where
48 T: State,
49 {
50 match self.msg.take() {
51 Some(m) => {
52 if m.is::<T>() {
53 Ok(*m.downcast::<T>().unwrap())
54 } else {
55 Err(BoxedDowncastErr)
56 }
57 }
58 None => Err(BoxedDowncastErr),
59 }
60 }
61}
62
63#[derive(Debug)]
65pub enum StopMessage {
66 Stop,
68 Reason(String),
70}
71
72impl std::fmt::Display for StopMessage {
73 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74 match self {
75 Self::Stop => write!(f, "Stop"),
76 Self::Reason(reason) => write!(f, "Stop (reason = {reason})"),
77 }
78 }
79}
80
81#[cfg(feature = "cluster")]
82impl crate::Message for StopMessage {}
83
84pub enum SupervisionEvent {
86 ActorStarted(super::actor_cell::ActorCell),
88 ActorTerminated(
93 super::actor_cell::ActorCell,
94 Option<BoxedState>,
95 Option<String>,
96 ),
97 ActorFailed(super::actor_cell::ActorCell, ActorProcessingErr),
99
100 ProcessGroupChanged(crate::pg::GroupChangeMessage),
102
103 #[cfg(feature = "cluster")]
105 PidLifecycleEvent(crate::registry::PidLifecycleEvent),
106}
107
108#[cfg(feature = "cluster")]
109impl crate::Message for SupervisionEvent {}
110
111impl SupervisionEvent {
112 pub fn actor_cell(&self) -> Option<&super::actor_cell::ActorCell> {
119 match self {
120 Self::ActorStarted(who)
121 | Self::ActorFailed(who, _)
122 | Self::ActorTerminated(who, _, _) => Some(who),
123 _ => None,
124 }
125 }
126
127 pub fn actor_id(&self) -> Option<super::actor_id::ActorId> {
133 self.actor_cell().map(|cell| cell.get_id())
134 }
135
136 #[cfg(feature = "monitors")]
142 pub(crate) fn clone_no_data(&self) -> Self {
143 match self {
144 Self::ActorStarted(who) => Self::ActorStarted(who.clone()),
145 Self::ActorFailed(who, what) => {
146 Self::ActorFailed(who.clone(), From::from(format!("{what}")))
147 }
148 Self::ProcessGroupChanged(what) => Self::ProcessGroupChanged(what.clone()),
149 Self::ActorTerminated(who, _state, msg) => {
150 Self::ActorTerminated(who.clone(), None, msg.as_ref().cloned())
151 }
152 #[cfg(feature = "cluster")]
153 Self::PidLifecycleEvent(evt) => Self::PidLifecycleEvent(evt.clone()),
154 }
155 }
156}
157
158impl Debug for SupervisionEvent {
159 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
160 write!(f, "Supervision event: {self}")
161 }
162}
163
164impl std::fmt::Display for SupervisionEvent {
165 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166 match self {
167 SupervisionEvent::ActorStarted(actor) => {
168 write!(f, "Started actor {actor:?}")
169 }
170 SupervisionEvent::ActorTerminated(actor, _, reason) => {
171 if let Some(r) = reason {
172 write!(f, "Stopped actor {actor:?} (reason = {r})")
173 } else {
174 write!(f, "Stopped actor {actor:?}")
175 }
176 }
177 SupervisionEvent::ActorFailed(actor, panic_msg) => {
178 write!(f, "Actor panicked {actor:?} - {panic_msg}")
179 }
180 SupervisionEvent::ProcessGroupChanged(change) => {
181 write!(
182 f,
183 "Process group {} in scope {} changed",
184 change.get_group(),
185 change.get_scope()
186 )
187 }
188 #[cfg(feature = "cluster")]
189 SupervisionEvent::PidLifecycleEvent(change) => {
190 write!(f, "PID lifecycle event {change:?}")
191 }
192 }
193 }
194}
195
196#[derive(Clone, Debug)]
198pub enum Signal {
199 Kill,
201}
202
203impl std::fmt::Display for Signal {
204 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
205 match self {
206 Self::Kill => {
207 write!(f, "killed")
208 }
209 }
210 }
211}