Skip to content
This repository was archived by the owner on Nov 9, 2019. It is now read-only.

Commit 4229e02

Browse files
committed
Added documentation for aktoro-runtime.
1 parent 0575b2a commit 4229e02

File tree

3 files changed

+125
-6
lines changed

3 files changed

+125
-6
lines changed

aktoro-raw/src/spawned.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ type ControllerError<A> = <Controller<A> as RawController<A>>::Error;
2222

2323
type Updated<A> = <<<A as Actor>::Context as Context<A>>::Updater as Updater<A>>::Updated;
2424

25+
/// A wrapper around an actor's
26+
/// message, control and update
27+
/// channels.
2528
pub struct Spawned<A: Actor> {
2629
sender: Sender<A>,
2730
ctrler: Controller<A>,
@@ -31,11 +34,6 @@ pub struct Spawned<A: Actor> {
3134
impl<A: Actor> Spawned<A> {
3235
/// Creates a new `Spawned` struct from an actor's
3336
/// context.
34-
///
35-
/// ## Note
36-
///
37-
/// This should only be used by a runtime after
38-
/// an actor has finished starting.
3937
pub fn new(ctx: &mut A::Context) -> Spawned<A> {
4038
Spawned {
4139
sender: ctx.sender().clone(),

aktoro-runtime/src/actor.rs

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,35 @@ pub(crate) struct Actor<A: raw::Actor> {
2525
}
2626

2727
#[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
2832
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
2937
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
3042
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
3147
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
3252
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
3357
Dead,
3458
}
3559

@@ -64,22 +88,35 @@ impl<A: raw::Actor> Actor<A> {
6488
killed: KilledSender,
6589
mut ctx: A::Context,
6690
) -> Option<Self> {
91+
// Sets the actor's status as starting
92+
// and call the `starting` method on it.
6793
ctx.set_status(A::Status::starting());
6894
act.starting(&mut ctx);
6995

96+
// If the actor has decided to stop
97+
// gracefully, we call its
98+
// `stopping` method.
7099
if ctx.status().is_stopping() {
71100
act.stopping(&mut ctx);
72101

73-
if ctx.status().is_stopped() {
102+
// If it has stopped, we set
103+
// its status as stopped.
104+
if ctx.status().is_stopping() {
74105
ctx.set_status(A::Status::stopped());
75106
}
76107
}
77108

109+
// If the actor's status is marked
110+
// as stopped, we call its `stopped`
111+
// method and change its status
112+
// as dead.
78113
if ctx.status().is_stopped() {
79114
act.stopped(&mut ctx);
80115
ctx.set_status(A::Status::dead());
81116
}
82117

118+
// If the actor is dead, we don't
119+
// spawn it in the background.
83120
if ctx.status().is_dead() {
84121
return None;
85122
}
@@ -94,13 +131,21 @@ impl<A: raw::Actor> Actor<A> {
94131
})
95132
}
96133

134+
/// Marks the actor as dead.
97135
fn dead(&mut self) -> Result<(), Error> {
136+
// We set the actor's status as
137+
// dead.
98138
self.ctx.set_status(A::Status::dead());
99139

140+
// We try to push the actor's
141+
// new status over its update
142+
// channel.
100143
if let Err(err) = self.ctx.update() {
101144
return Err(Box::new(err).into());
102145
}
103146

147+
// We try to notify the actor's
148+
// death over the killed channel.
104149
if let Err(err) = self.killed.killed(self.id) {
105150
return Err(Box::new(err).into());
106151
}
@@ -152,6 +197,8 @@ impl raw::Status for Status {
152197
}
153198

154199
impl KillSender {
200+
/// Kills the actor by sending a
201+
/// message over its kill channel.
155202
pub(crate) fn kill(&mut self) {
156203
if let Some(notify) = self.0.take() {
157204
notify.done();
@@ -161,6 +208,7 @@ impl KillSender {
161208
}
162209

163210
impl KilledSender {
211+
/// Notifies that the actor died.
164212
fn killed(&mut self, id: u64) -> Result<(), TrySendError<u64>> {
165213
self.0.try_send(id)
166214
}
@@ -173,51 +221,79 @@ impl<A: raw::Actor> Future for Actor<A> {
173221
let actor = self.get_mut();
174222

175223
loop {
224+
// If the actor has been asked
225+
// to die, we kill it.
176226
match Pin::new(&mut actor.kill).poll(ctx) {
177227
Poll::Ready(()) => actor.act.stopped(&mut actor.ctx),
178228
Poll::Pending => (),
179229
}
180230

231+
// If the actor's status is marked
232+
// as stopping, we call `stopping`
233+
// on it.
181234
if actor.ctx.status().is_stopping() {
182235
actor.act.stopping(&mut actor.ctx);
183236

237+
// If the actor's status hasn't
238+
// changed, we set it as stopped.
184239
if actor.ctx.status().is_stopping() {
185240
actor.ctx.set_status(A::Status::stopped());
186241
}
187242
}
188243

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.
189248
if actor.ctx.status().is_stopped() {
190249
actor.act.stopped(&mut actor.ctx);
191250
return Poll::Ready(actor.dead());
192251
}
193252

253+
// If the actor's status is marked
254+
// as dead, we notify that the actor
255+
// is dead over the killed channel.
194256
if actor.ctx.status().is_dead() {
195257
return Poll::Ready(actor.dead());
196258
}
197259

260+
// If `started` hasn't been called
261+
// on the actor, we call it.
198262
if !actor.started {
199263
actor.ctx.set_status(A::Status::started());
200264
actor.act.started(&mut actor.ctx);
265+
// We save that the actor's
266+
// `started` method has been
267+
// called.
201268
actor.started = true;
202269
continue;
203270
}
204271

205272
match Pin::new(&mut actor.ctx).poll_next(ctx) {
206273
Poll::Ready(Some(work)) => match work {
274+
// If the context received an
275+
// action for the actor to handle,
276+
// we do so.
207277
raw::Work::Action(mut action) => {
208278
if let Err(err) = action.handle(&mut actor.act, &mut actor.ctx) {
209279
return Poll::Ready(Err(Error::std(err).add_res(actor.dead())));
210280
}
211281

212282
continue;
213283
}
284+
// If the context has been asked
285+
// to get an event handled by the
286+
// actor, we do so.
214287
raw::Work::Event(mut event) => {
215288
if let Err(err) = event.handle(&mut actor.act, &mut actor.ctx) {
216289
return Poll::Ready(Err(Error::std(err).add_res(actor.dead())));
217290
}
218291

219292
continue;
220293
}
294+
// If the context has received a
295+
// message for the actor to handle,
296+
// we do so.
221297
raw::Work::Message(mut msg) => {
222298
if let Err(err) = msg.handle(&mut actor.act, &mut actor.ctx) {
223299
return Poll::Ready(Err(Error::std(err).add_res(actor.dead())));
@@ -227,6 +303,10 @@ impl<A: raw::Actor> Future for Actor<A> {
227303
}
228304
raw::Work::Update => continue,
229305
},
306+
// If the actor's context `Work`
307+
// stream has been closed, we
308+
// change the actor's status as
309+
// being stopped.
230310
Poll::Ready(None) => {
231311
actor.ctx.set_status(A::Status::stopped());
232312
continue;

aktoro-runtime/src/runtime.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,42 @@ use crate::actor::KilledRecver;
1818
use crate::actor::KilledSender;
1919
use crate::error::Error;
2020

21+
/// An actor runtime using the [`runtime`]
22+
///
23+
/// [`runtime`]: https://docs.rs/crates/runtime
2124
pub struct Runtime {
25+
/// A map matching an actor's ID with
26+
/// a sender for its kill channel.
2227
actors: FnvHashMap<u64, Kill>,
28+
/// A sender for the actors' killed
29+
/// channel (it will be cloned and
30+
/// passed to all new actors).
2331
sender: KilledSender,
32+
/// A receiver the the actors' killed
33+
/// channel, notified when an actor
34+
/// has stopped/been killed.
2435
recver: KilledRecver,
36+
/// A fast (non-cryptographic) random
37+
/// number generator.
2538
rng: Xoshiro512StarStar,
2639
}
2740

41+
/// A future that resolves when all the
42+
/// runtime's actors have been stopped.
2843
pub struct Stop(Wait);
2944

45+
/// A future that resolves when all the
46+
/// runtime's actors have been stopped.
3047
pub struct Wait {
3148
rt: Runtime,
49+
/// Contains a list of all the errors
50+
/// that happened while waiting for
51+
/// the actors to stop.
3252
errors: Vec<Error>,
3353
}
3454

3555
impl Runtime {
56+
/// Creates a new `Runtime`.
3657
pub fn new() -> Self {
3758
Runtime::default()
3859
}
@@ -45,24 +66,35 @@ impl raw::Runtime for Runtime {
4566
type Error = Error;
4667

4768
fn spawn<A: raw::Actor>(&mut self, actor: A) -> Option<raw::Spawned<A>> {
69+
// Create a new context for the actor.
4870
let mut ctx = A::Context::new();
4971

72+
// Create a new `Spawned` struct from
73+
// the actor's context.
5074
let spawned = raw::Spawned::new(&mut ctx);
5175

76+
// Generate the actor's ID.
5277
let id = self.rng.next_u64();
5378

79+
// Create the actor's kill channel.
5480
let (sender, recver) = actor::new_kill();
5581

82+
// Try to create the actor (fails if
83+
// it refused to start).
5684
let actor = Actor::new(id, actor, recver, self.sender.clone(), ctx)?;
5785

86+
// Save the actor's kill channel's
87+
// sender.
5888
self.actors.insert(id, sender);
5989

90+
// Spawn the actor.
6091
runtime::spawn(actor);
6192

6293
Some(spawned)
6394
}
6495

6596
fn stop(mut self) -> Stop {
97+
// Ask for each actor to stop.
6698
for (_, actor) in self.actors.iter_mut() {
6799
actor.kill();
68100
}
@@ -82,6 +114,11 @@ impl Future for Stop {
82114
type Output = Result<(), Error>;
83115

84116
fn poll(self: Pin<&mut Self>, ctx: &mut FutContext) -> Poll<Result<(), Error>> {
117+
// `Stop` is just a wrapper
118+
// arround `Wait` (what differs
119+
// is what happens before it
120+
// is returned by the `stop`
121+
// method).
85122
Pin::new(&mut self.get_mut().0).poll(ctx)
86123
}
87124
}
@@ -98,12 +135,16 @@ impl Future for Wait {
98135
return Poll::Ready(Ok(()));
99136
}
100137

138+
// We try to poll from the actors'
139+
// kill channel's receiver.
101140
match Pin::new(&mut rt.recver).poll_next(ctx) {
102141
Poll::Ready(Some(actor)) => {
103142
if rt.actors.remove(&actor).is_none() {
104143
wait.errors.push(Error::already_removed(actor));
105144
}
106145
}
146+
// If the channel has been closed,
147+
// we stop the future.
107148
Poll::Ready(None) => {
108149
if wait.errors.len() > 1 {
109150
return Poll::Ready(Err(Error::multiple(wait.errors.split_off(0))));

0 commit comments

Comments
 (0)