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
use Future;
use ;
use warn;
use JoinHandle;
use crateResult;
use crateActorRef;
use crateControl;
use crateActorExecutor;
/// The default size of the actor channel buffer. The channel buffers incoming messages, once it is
/// full then sending threads will wait for space in the buffer.
const DEFAULT_ACTOR_BUFFER_SIZE: usize = 10;
/// The Actor trait. This is the trait that structs will need to implement to function as an actor.
///
/// An actor is an independent computational unit that communicates through messages and maintains
/// it's own private state. In this library, each actor has its own single thread of control, which
/// means that each actor runs independently from anything else and each actor runs in a single
/// threaded fashion meaning that there are no concurrency issues within the actor itself.
///
/// A struct can become an actor by implementing this trait. Instances of the actor are created
/// using the [create_actor()] function. This function returns an [ActorRef] which is used to
/// control the instance and to send it messages. [ActorRef]s can be freely cloned and sent, there
/// can be as many references to an actor instance as required.
///
/// The state of the actor is held in the struct that implements the Actor trait and is maintained
/// by the Actor functions.
///
/// Once created, the actor executor will call the following functions as required:
///
/// * on_initialization() - this will be called immediately after the actor is created
/// * handle_sends() - this is called whenever the actor receives a send message
/// * handle_calls() - this is called whenever the actor receives a call message
/// * on_shutdown() - this is called when the actor is being shut down
///
/// These functions return a [Control] enum, which enables the actor to control its execution,
/// including shutdown and termination. [Control] also enables the integration of tasks
/// from outside the actor framework. See [Control] for more information on the types of actions
/// that can be initiated.
///
/// For more details on these functions, see the individual function documentation.
///
/// ## Integration of Futures
///
/// This framework provides the capability to integrate with futures created outside of the
/// framework.
///
/// ## Shutdown, and Termination
///
/// todo: implement
/// A shutdown is a controlled shutdown of the actor. It completes execution of all messages
/// that were received prior to the shutdown instruction, awaits any registered futures, and then
/// shuts down. Messages that are received after the shutdown instruction
/// are discarded. In the case of send messages this has no direct effect and in the case of call messages
/// this will result in an error for the calling task. The on_shutdown() function is called.
///
/// todo: implement
/// A termination is an quicker shutdown of the actor. Messages that were sent
/// prior to the termination are discarded. Any futures that were registered and that are still active
/// are cancelled.
///
/// ## Panics
/// todo: what happens if an actor panics?
///
/// Create an instance of an actor using default configuration.
pub async