coerce/
lib.rs

1//! Coerce is a framework for creating distributed, event-driven applications, implementing [Carl Hewitt]'s [actor model].
2//!
3//! Taking inspiration from [akka], [akka.net], [actix] and [Orleans], Coerce brings
4//! the power and flexibility of distributed actors and other industry-leading patterns to your Rust toolbox and
5//! provides the required primitives for creating highly available, fault tolerant distributed applications.
6//!
7//! Coerce uses [tokio]'s asynchronous runtime and IO framework to ensure best-in-class performance
8//! and concurrency, and seamless compatibility with other `async` libraries.
9//!
10//! Asynchronous traits are currently achieved by using the [async_trait] macro, with the intention
11//! to drop the dependency once `async fn in trait` is generally available in stable Rust.
12//!
13//! [Carl Hewitt]: https://en.wikipedia.org/wiki/Carl_Hewitt
14//! [actor model]: https://en.wikipedia.org/wiki/Actor_model
15//! [akka]: https://github.com/akka/akka
16//! [akka.net]: https://github.com/akkadotnet/akka.net
17//! [actix]: https://github.com/actix/actix
18//! [Orleans]: https://github.com/dotnet/orleans
19//! [tokio]: https://github.com/tokio/tokio-rs
20//! [async_trait]: https://github.com/dtolnay/async-trait
21//!
22//!
23//! # Features
24//! - [Asynchronous Actors]
25//! - [Actor References]
26//! - [Asynchronous Message Handling]
27//! - [Actor Supervision]
28//! - [Actor Persistence]
29//!     - [Event sourcing]
30//!     - [Snapshots]
31//!     - [Pluggable Storage Backend]
32//! - [Clustering]
33//! - [Distributed PubSub]
34//! - [Distributed Sharding]
35//! - [Health Checks]
36//! - [Actor Metrics]
37//! - [Networking Metrics]
38//!
39//! [Asynchronous Actors]: crate::actor
40//! [Actor References]: crate::actor::ActorRef
41//! [Asynchronous Message Handling]: crate::actor::message
42//! [Actor Supervision]: crate::actor::supervised
43//! [Actor Persistence]: crate::persistent::actor::PersistentActor
44//! [Event sourcing]: crate::persistent::actor::Recover
45//! [Snapshots]: crate::persistent::actor::RecoverSnapshot
46//! [Pluggable Storage Backend]: crate::persistent::journal::storage::JournalStorage
47//! [Clustering]: crate::remote::cluster
48//! [Distributed PubSub]: crate::remote::stream
49//! [Distributed Sharding]: crate::sharding
50//! [Health Checks]: crate::remote::heartbeat::health
51//! [Actor Metrics]: crate::actor::metrics
52//! [Networking Metrics]: crate::remote::net::metrics
53//!
54//! ## Feature Flags
55//! Coerce is split into numerous features, which allows you to choose which Coerce features are to
56//! be compiled, allowing you to speed up compilation if there are only specific modules your application uses:
57//!
58//! - `full` - Enables all features
59//! - `remote` - Enables remoting and clustering
60//! - `persistence` - Enables actor persistence
61//! - `metrics` - Enables actor metrics + metrics exporter
62//! - `sharding` - Enables distributed sharding
63//! - `actor-tracing` - Enables actor tracing
64//! - `api` - Enables HTTP API server
65//! - `client-auth-jwt` - Enables JWT authentication between Coerce cluster nodes
66//!
67//! # Getting Started
68//! The entry point into the Coerce runtime is an [`ActorSystem`]. Every [`ActorSystem`] has an ID
69//! a name and an [`ActorScheduler`]. The [`ActorScheduler`] acts as a local registry and is
70//! responsible for keeping track of actors, allowing retrieval of [`LocalActorRef`]s by [`ActorId`].
71//!
72//! Actors can be created by either using the [`IntoActor`] trait on instances of any type that implement
73//! the [`Actor`] trait, or by calling `new_actor` on the [`ActorSystem`] directly.
74//!
75//! At a high level, there are 2 types of actors that can be created, [`Tracked`] and [`Anonymous`].
76//! The only differences between them are that [`Tracked`] actors are registered with the
77//! [`ActorScheduler`], which means their [`LocalActorRef`] can be retrieved and they can be communicated
78//! with remotely, but an [`Anonymous`] actor cannot be retrieved and is not available for remote communication.
79//!
80//! [`ActorSystem`]: crate::actor::system::ActorSystem
81//! [`ActorScheduler`]: crate::actor::scheduler::ActorScheduler
82//! [`LocalActorRef`]: crate::actor::LocalActorRef
83//! [`ActorId`]: crate::actor::ActorId
84//! [`IntoActor`]: crate::actor::IntoActor
85//! [`Actor`]: crate::actor::Actor
86//! [`Tracked`]: crate::actor::scheduler::ActorType::Tracked
87//! [`Anonymous`]: crate::actor::scheduler::ActorType::Anonymous
88//!
89//!
90//! ## Actor Example
91//! ```rust
92//!
93//! use coerce::actor::{
94//!     Actor, IntoActor,
95//!     message::{Message, Handler},
96//!     context::ActorContext,
97//!     system::ActorSystem
98//! };
99//!
100//! #[tokio::main]
101//! pub async fn main() {
102//!     let system = ActorSystem::new();
103//!     let actor = PlayerActor::default()
104//!                 .into_actor(Some("player-actor-1"), &system)
105//!                 .await
106//!                 .unwrap();
107//!
108//!     let _ = actor.notify(PointsScored(1));
109//!     let _ = actor.notify(PointsScored(2));
110//!     let _ = actor.notify(PointsScored(3));
111//!
112//!     let points = actor.send(GetPoints).await.ok();
113//!     assert_eq!(points, Some(6))
114//! }
115//!
116//! #[derive(Default)]
117//! struct PlayerActor {
118//!     points: usize,
119//! }
120//!
121//! impl Actor for PlayerActor { }
122//!
123//! pub struct PointsScored(usize);
124//!
125//! impl Message for PointsScored {
126//!     type Result = ();
127//! }
128//!
129//! pub struct GetPoints;
130//!
131//! impl Message for GetPoints {
132//!     type Result = usize;
133//! }
134//!
135//! #[async_trait::async_trait]
136//! impl Handler<PointsScored> for PlayerActor {
137//!     async fn handle(&mut self, message: PointsScored, ctx: &mut ActorContext) {
138//!         self.points += message.0;
139//!     }
140//! }
141//!
142//! #[async_trait::async_trait]
143//! impl Handler<GetPoints> for PlayerActor {
144//!     async fn handle(&mut self, message: GetPoints, ctx: &mut ActorContext) -> usize {
145//!         self.points
146//!     }
147//! }
148//!
149//! ```
150//!
151
152#[macro_use]
153extern crate async_trait;
154
155#[macro_use]
156extern crate serde;
157
158#[macro_use]
159extern crate lazy_static;
160
161#[cfg(feature = "metrics")]
162#[macro_use]
163extern crate metrics;
164
165#[cfg(feature = "api")]
166#[macro_use]
167extern crate utoipa;
168
169#[macro_use]
170extern crate tracing;
171
172pub mod actor;
173
174#[cfg(feature = "persistence")]
175pub mod persistent;
176
177#[cfg(feature = "remote")]
178pub mod remote;
179
180#[cfg(feature = "sharding")]
181pub mod sharding;
182
183pub(crate) const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION");