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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//! Coerce is a framework for creating distributed, event-driven applications, implementing [Carl Hewitt]'s [actor model].
//!
//! Taking inspiration from [akka], [akka.net], [actix] and [Orleans], Coerce brings
//! the power and flexibility of distributed actors and other industry-leading patterns to your Rust toolbox and
//! provides the required primitives for creating highly available, fault tolerant distributed applications.
//!
//! Coerce uses [tokio]'s asynchronous runtime and IO framework to ensure best-in-class performance
//! and concurrency, and seamless compatibility with other `async` libraries.
//!
//! Asynchronous traits are currently achieved by using the [async_trait] macro, with the intention
//! to drop the dependency once `async fn in trait` is generally available in stable Rust.
//!
//! [Carl Hewitt]: https://en.wikipedia.org/wiki/Carl_Hewitt
//! [actor model]: https://en.wikipedia.org/wiki/Actor_model
//! [akka]: https://github.com/akka/akka
//! [akka.net]: https://github.com/akkadotnet/akka.net
//! [actix]: https://github.com/actix/actix
//! [Orleans]: https://github.com/dotnet/orleans
//! [tokio]: https://github.com/tokio/tokio-rs
//! [async_trait]: https://github.com/dtolnay/async-trait
//!
//!
//! # Features
//! - [Asynchronous Actors]
//! - [Actor References]
//! - [Asynchronous Message Handling]
//! - [Actor Supervision]
//! - [Actor Persistence]
//! - [Event sourcing]
//! - [Snapshots]
//! - [Pluggable Storage Backend]
//! - [Clustering]
//! - [Distributed PubSub]
//! - [Distributed Sharding]
//! - [Health Checks]
//! - [Actor Metrics]
//! - [Networking Metrics]
//!
//! [Asynchronous Actors]: crate::actor
//! [Actor References]: crate::actor::ActorRef
//! [Asynchronous Message Handling]: crate::actor::message
//! [Actor Supervision]: crate::actor::supervised
//! [Actor Persistence]: crate::persistent::actor::PersistentActor
//! [Event sourcing]: crate::persistent::actor::Recover
//! [Snapshots]: crate::persistent::actor::RecoverSnapshot
//! [Pluggable Storage Backend]: crate::persistent::journal::storage::JournalStorage
//! [Clustering]: crate::remote::cluster
//! [Distributed PubSub]: crate::remote::stream
//! [Distributed Sharding]: crate::sharding
//! [Health Checks]: crate::remote::heartbeat::health
//! [Actor Metrics]: crate::actor::metrics
//! [Networking Metrics]: crate::remote::net::metrics
//!
//! ## Feature Flags
//! Coerce is split into numerous features, which allows you to choose which Coerce features are to
//! be compiled, allowing you to speed up compilation if there are only specific modules your application uses:
//!
//! - `full` - Enables all features
//! - `remote` - Enables remoting and clustering
//! - `persistence` - Enables actor persistence
//! - `metrics` - Enables actor metrics + metrics exporter
//! - `sharding` - Enables distributed sharding
//! - `actor-tracing` - Enables actor tracing
//! - `api` - Enables HTTP API server
//! - `client-auth-jwt` - Enables JWT authentication between Coerce cluster nodes
//!
//! # Getting Started
//! The entry point into the Coerce runtime is an [`ActorSystem`]. Every [`ActorSystem`] has an ID
//! a name and an [`ActorScheduler`]. The [`ActorScheduler`] acts as a local registry and is
//! responsible for keeping track of actors, allowing retrieval of [`LocalActorRef`]s by [`ActorId`].
//!
//! Actors can be created by either using the [`IntoActor`] trait on instances of any type that implement
//! the [`Actor`] trait, or by calling `new_actor` on the [`ActorSystem`] directly.
//!
//! At a high level, there are 2 types of actors that can be created, [`Tracked`] and [`Anonymous`].
//! The only differences between them are that [`Tracked`] actors are registered with the
//! [`ActorScheduler`], which means their [`LocalActorRef`] can be retrieved and they can be communicated
//! with remotely, but an [`Anonymous`] actor cannot be retrieved and is not available for remote communication.
//!
//! [`ActorSystem`]: crate::actor::system::ActorSystem
//! [`ActorScheduler`]: crate::actor::scheduler::ActorScheduler
//! [`LocalActorRef`]: crate::actor::LocalActorRef
//! [`ActorId`]: crate::actor::ActorId
//! [`IntoActor`]: crate::actor::IntoActor
//! [`Actor`]: crate::actor::Actor
//! [`Tracked`]: crate::actor::scheduler::ActorType::Tracked
//! [`Anonymous`]: crate::actor::scheduler::ActorType::Anonymous
//!
//!
//! ## Actor Example
//! ```rust
//!
//! use coerce::actor::{
//! Actor, IntoActor,
//! message::{Message, Handler},
//! context::ActorContext,
//! system::ActorSystem
//! };
//!
//! #[tokio::main]
//! pub async fn main() {
//! let system = ActorSystem::new();
//! let actor = PlayerActor::default()
//! .into_actor(Some("player-actor-1"), &system)
//! .await
//! .unwrap();
//!
//! let _ = actor.notify(PointsScored(1));
//! let _ = actor.notify(PointsScored(2));
//! let _ = actor.notify(PointsScored(3));
//!
//! let points = actor.send(GetPoints).await.ok();
//! assert_eq!(points, Some(6))
//! }
//!
//! #[derive(Default)]
//! struct PlayerActor {
//! points: usize,
//! }
//!
//! impl Actor for PlayerActor { }
//!
//! pub struct PointsScored(usize);
//!
//! impl Message for PointsScored {
//! type Result = ();
//! }
//!
//! pub struct GetPoints;
//!
//! impl Message for GetPoints {
//! type Result = usize;
//! }
//!
//! #[async_trait::async_trait]
//! impl Handler<PointsScored> for PlayerActor {
//! async fn handle(&mut self, message: PointsScored, ctx: &mut ActorContext) {
//! self.points += message.0;
//! }
//! }
//!
//! #[async_trait::async_trait]
//! impl Handler<GetPoints> for PlayerActor {
//! async fn handle(&mut self, message: GetPoints, ctx: &mut ActorContext) -> usize {
//! self.points
//! }
//! }
//!
//! ```
//!
extern crate async_trait;
extern crate serde;
extern crate lazy_static;
extern crate metrics;
extern crate utoipa;
extern crate tracing;
pub const CARGO_PKG_VERSION: &str = env!;