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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//! Actor is an entity capable of receiving and processing messages.
//!
//! For details, see the [`Actor`] documentation.
use async_trait;
use crate::;
/// Action to be performed after `Actor::stopping` is called.
///
/// In this method, actor can decide whether it will indeed stop
/// or keep running.
/// Actor is an entity capable of receiving and processing messages.
///
/// Each actor runs in an associated [`Context`] object that is capable
/// of managing the message delivery and maintaing the actor state.
///
/// Minimal implementation of an actor doesn't require any methods on it
/// and can be used on (almost) any type as a marker.
///
/// However, optional methods for better control of the actor lifespan
/// are provided:
///
/// - `started` method is called once [`Context`] was launched and is about
/// to start processing incoming messages.
/// - `stopping` method is called after either [`Address::stop`] method was
/// executed, or all the [`Address`] objects connected to an actor were
/// dropped.
/// - `stopped` method is a notification signaling that the [`Context`] future
/// is finishing its execution and after this call `Actor` object will be
/// dropped.
///
/// ## Stopping
///
/// Actor can stop in the following scenarios:
///
/// - [`Address::stop`] method was invoked.
/// - Runtime in which [`Context`] is spawned was shutdown.
///
/// ## Prerequisites
///
/// As actors must be suitable for using in the multithreaded runtimes,
/// each type implementing `Actor` must be [`Send`], [`Sync`] and [`'static`][static_lt].
///
/// Additionally, it must implement [`Unpin`](std::marker::Unpin)
///
/// [static_lt]: https://doc.rust-lang.org/reference/types/trait-object.html#trait-object-lifetime-bounds
///
/// ## Extensions
///
/// When one of the runtime features is enabled in this crate, there is also an extension trait available:
/// [`RuntimeActorExt`], which provides more convenient interface for spawning actors, e.g. [`RuntimeActorExt::spawn`].
///
/// ## Examples
///
/// This example assumes that `messages` is used with `rt-tokio` feature enabled.
///
/// ```rust
/// # use messages::prelude::*;
///
/// struct Ping;
///
/// #[async_trait]
/// impl Actor for Ping {
/// async fn started(&mut self) {
/// println!("Actor was started");
/// }
///
/// async fn stopping(&mut self) -> ActorAction {
/// println!("Actor is stopping");
/// ActorAction::Stop
/// }
///
/// fn stopped(&mut self) {
/// println!("Actor is stopped");
/// }
/// }
///
/// #[tokio::main]
/// async fn main() {
/// let mut addr = Ping.spawn();
/// addr.stop().await;
/// addr.wait_for_stop().await;
/// }
/// ```
cfg_runtime!