@@ -25,11 +25,35 @@ pub(crate) struct Actor<A: raw::Actor> {
25
25
}
26
26
27
27
#[ derive( Eq , PartialEq , Debug , Clone ) ]
28
+ /// A default implementation for the
29
+ /// [`aktoro-raw::Status`] trait.
30
+ ///
31
+ /// [`aktoro-raw::Status`]: https://docs.rs/aktoro-raw/struct.Status.html
28
32
pub enum Status {
33
+ /// The status that an actor should have
34
+ /// before [`Actor::starting`] is called.
35
+ ///
36
+ /// [`Actor::starting`]: https://docs.rs/aktoro-raw/trait.Actor.html#method.starting
29
37
Starting ,
38
+ /// The status that an actor should have
39
+ /// before [`Actor::started`] is called.
40
+ ///
41
+ /// [`Actor::started`]: https://docs.rs/aktoro-raw/trait.Actor.html#method.started
30
42
Started ,
43
+ /// The status that an actor should have
44
+ /// before [`Actor::stopping`] is called.
45
+ ///
46
+ /// [`Actor::stopped`]: https://docs.rs/aktoro-raw/trait.Actor.html#method.stopping
31
47
Stopping ,
48
+ /// The status that an actor should have
49
+ /// before [`Actor::stopped`] is called.
50
+ ///
51
+ /// [`Actor::stopped`]: https://docs.rs/aktoro-raw/trait.Actor.html#method.stopped
32
52
Stopped ,
53
+ /// The status that an actor has after
54
+ /// [`Actor::stopped`] has been called.
55
+ ///
56
+ /// [`Actor::stopped`]: https://docs.rs/aktoro-raw/trait.Actor.html#method.stropped
33
57
Dead ,
34
58
}
35
59
@@ -64,22 +88,35 @@ impl<A: raw::Actor> Actor<A> {
64
88
killed : KilledSender ,
65
89
mut ctx : A :: Context ,
66
90
) -> Option < Self > {
91
+ // Sets the actor's status as starting
92
+ // and call the `starting` method on it.
67
93
ctx. set_status ( A :: Status :: starting ( ) ) ;
68
94
act. starting ( & mut ctx) ;
69
95
96
+ // If the actor has decided to stop
97
+ // gracefully, we call its
98
+ // `stopping` method.
70
99
if ctx. status ( ) . is_stopping ( ) {
71
100
act. stopping ( & mut ctx) ;
72
101
73
- if ctx. status ( ) . is_stopped ( ) {
102
+ // If it has stopped, we set
103
+ // its status as stopped.
104
+ if ctx. status ( ) . is_stopping ( ) {
74
105
ctx. set_status ( A :: Status :: stopped ( ) ) ;
75
106
}
76
107
}
77
108
109
+ // If the actor's status is marked
110
+ // as stopped, we call its `stopped`
111
+ // method and change its status
112
+ // as dead.
78
113
if ctx. status ( ) . is_stopped ( ) {
79
114
act. stopped ( & mut ctx) ;
80
115
ctx. set_status ( A :: Status :: dead ( ) ) ;
81
116
}
82
117
118
+ // If the actor is dead, we don't
119
+ // spawn it in the background.
83
120
if ctx. status ( ) . is_dead ( ) {
84
121
return None ;
85
122
}
@@ -94,13 +131,21 @@ impl<A: raw::Actor> Actor<A> {
94
131
} )
95
132
}
96
133
134
+ /// Marks the actor as dead.
97
135
fn dead ( & mut self ) -> Result < ( ) , Error > {
136
+ // We set the actor's status as
137
+ // dead.
98
138
self . ctx . set_status ( A :: Status :: dead ( ) ) ;
99
139
140
+ // We try to push the actor's
141
+ // new status over its update
142
+ // channel.
100
143
if let Err ( err) = self . ctx . update ( ) {
101
144
return Err ( Box :: new ( err) . into ( ) ) ;
102
145
}
103
146
147
+ // We try to notify the actor's
148
+ // death over the killed channel.
104
149
if let Err ( err) = self . killed . killed ( self . id ) {
105
150
return Err ( Box :: new ( err) . into ( ) ) ;
106
151
}
@@ -152,6 +197,8 @@ impl raw::Status for Status {
152
197
}
153
198
154
199
impl KillSender {
200
+ /// Kills the actor by sending a
201
+ /// message over its kill channel.
155
202
pub ( crate ) fn kill ( & mut self ) {
156
203
if let Some ( notify) = self . 0 . take ( ) {
157
204
notify. done ( ) ;
@@ -161,6 +208,7 @@ impl KillSender {
161
208
}
162
209
163
210
impl KilledSender {
211
+ /// Notifies that the actor died.
164
212
fn killed ( & mut self , id : u64 ) -> Result < ( ) , TrySendError < u64 > > {
165
213
self . 0 . try_send ( id)
166
214
}
@@ -173,51 +221,79 @@ impl<A: raw::Actor> Future for Actor<A> {
173
221
let actor = self . get_mut ( ) ;
174
222
175
223
loop {
224
+ // If the actor has been asked
225
+ // to die, we kill it.
176
226
match Pin :: new ( & mut actor. kill ) . poll ( ctx) {
177
227
Poll :: Ready ( ( ) ) => actor. act . stopped ( & mut actor. ctx ) ,
178
228
Poll :: Pending => ( ) ,
179
229
}
180
230
231
+ // If the actor's status is marked
232
+ // as stopping, we call `stopping`
233
+ // on it.
181
234
if actor. ctx . status ( ) . is_stopping ( ) {
182
235
actor. act . stopping ( & mut actor. ctx ) ;
183
236
237
+ // If the actor's status hasn't
238
+ // changed, we set it as stopped.
184
239
if actor. ctx . status ( ) . is_stopping ( ) {
185
240
actor. ctx . set_status ( A :: Status :: stopped ( ) ) ;
186
241
}
187
242
}
188
243
244
+ // If the actor's status is marked
245
+ // as stopped, we call `stopped`
246
+ // ont it and notify that the actor
247
+ // is dead over the killed channel.
189
248
if actor. ctx . status ( ) . is_stopped ( ) {
190
249
actor. act . stopped ( & mut actor. ctx ) ;
191
250
return Poll :: Ready ( actor. dead ( ) ) ;
192
251
}
193
252
253
+ // If the actor's status is marked
254
+ // as dead, we notify that the actor
255
+ // is dead over the killed channel.
194
256
if actor. ctx . status ( ) . is_dead ( ) {
195
257
return Poll :: Ready ( actor. dead ( ) ) ;
196
258
}
197
259
260
+ // If `started` hasn't been called
261
+ // on the actor, we call it.
198
262
if !actor. started {
199
263
actor. ctx . set_status ( A :: Status :: started ( ) ) ;
200
264
actor. act . started ( & mut actor. ctx ) ;
265
+ // We save that the actor's
266
+ // `started` method has been
267
+ // called.
201
268
actor. started = true ;
202
269
continue ;
203
270
}
204
271
205
272
match Pin :: new ( & mut actor. ctx ) . poll_next ( ctx) {
206
273
Poll :: Ready ( Some ( work) ) => match work {
274
+ // If the context received an
275
+ // action for the actor to handle,
276
+ // we do so.
207
277
raw:: Work :: Action ( mut action) => {
208
278
if let Err ( err) = action. handle ( & mut actor. act , & mut actor. ctx ) {
209
279
return Poll :: Ready ( Err ( Error :: std ( err) . add_res ( actor. dead ( ) ) ) ) ;
210
280
}
211
281
212
282
continue ;
213
283
}
284
+ // If the context has been asked
285
+ // to get an event handled by the
286
+ // actor, we do so.
214
287
raw:: Work :: Event ( mut event) => {
215
288
if let Err ( err) = event. handle ( & mut actor. act , & mut actor. ctx ) {
216
289
return Poll :: Ready ( Err ( Error :: std ( err) . add_res ( actor. dead ( ) ) ) ) ;
217
290
}
218
291
219
292
continue ;
220
293
}
294
+ // If the context has received a
295
+ // message for the actor to handle,
296
+ // we do so.
221
297
raw:: Work :: Message ( mut msg) => {
222
298
if let Err ( err) = msg. handle ( & mut actor. act , & mut actor. ctx ) {
223
299
return Poll :: Ready ( Err ( Error :: std ( err) . add_res ( actor. dead ( ) ) ) ) ;
@@ -227,6 +303,10 @@ impl<A: raw::Actor> Future for Actor<A> {
227
303
}
228
304
raw:: Work :: Update => continue ,
229
305
} ,
306
+ // If the actor's context `Work`
307
+ // stream has been closed, we
308
+ // change the actor's status as
309
+ // being stopped.
230
310
Poll :: Ready ( None ) => {
231
311
actor. ctx . set_status ( A :: Status :: stopped ( ) ) ;
232
312
continue ;
0 commit comments