Skip to main content

acktor/
signal.rs

1use std::future::{self, Future};
2
3use crate::actor::{Actor, ActorContext};
4use crate::message::{Handler, Message};
5use crate::utils::debug_trace;
6
7/// A message which is used to stop/terminate an actor.
8///
9/// `Handler<Signal>` is implemented for all actors automatically.
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11#[repr(u8)]
12pub enum Signal {
13    /// Stop the actor.
14    ///
15    /// Set the actor's state to [`Stopping`][crate::actor::ActorState::Stopping] and trigger
16    /// the [`stopping`][Actor::stopping] method of the actor. The actor might be able to resume
17    /// by itself.
18    Stop,
19    /// Terminate the actor.
20    ///
21    /// Set the actor's state to [`Stopped`][crate::actor::ActorState::Stopped] and trigger
22    /// the [`post_stop`][Actor::post_stop] method. Any messages still queued in the mailbox
23    /// behind this signal are dropped without being handled.
24    Terminate,
25}
26
27impl Message for Signal {
28    type Result = ();
29}
30
31impl TryFrom<u8> for Signal {
32    type Error = ();
33
34    fn try_from(value: u8) -> Result<Self, Self::Error> {
35        match value {
36            0 => Ok(Signal::Stop),
37            1 => Ok(Signal::Terminate),
38            _ => Err(()),
39        }
40    }
41}
42
43impl<A> Handler<Signal> for A
44where
45    A: Actor,
46    A::Context: ActorContext<A>,
47{
48    type Result = ();
49
50    fn handle(
51        &mut self,
52        msg: Signal,
53        ctx: &mut Self::Context,
54    ) -> impl Future<Output = Self::Result> + Send {
55        debug_trace!("Handle command {:?}", msg);
56
57        match msg {
58            Signal::Stop => {
59                ctx.stop();
60            }
61            Signal::Terminate => {
62                ctx.terminate();
63            }
64        }
65
66        future::ready(())
67    }
68}
69
70#[cfg(feature = "identifier")]
71impl crate::stable_type_id::StableId for Signal {
72    const TYPE_ID: crate::stable_type_id::StableTypeId =
73        crate::stable_type_id::StableTypeId::from_stable_type_name(concat!(
74            module_path!(),
75            "::",
76            "Signal"
77        ));
78}
79
80#[cfg(test)]
81mod tests {
82    use pretty_assertions::assert_eq;
83
84    use super::*;
85
86    #[test]
87    fn test_signal_try_from() {
88        assert_eq!(Signal::try_from(0), Ok(Signal::Stop));
89        assert_eq!(Signal::try_from(1), Ok(Signal::Terminate));
90        assert_eq!(Signal::try_from(2), Err(()));
91    }
92}