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