coerce/remote/mod.rs
1//! Coerce Remoting
2//!
3//! Coerce clusters are identified by a [`NodeId`] and a string-based node tag.
4//!
5//! The easiest way to create a full, batteries-included clustered actor system, is by
6//! using the [`RemoteActorSystemBuilder`]. From here, you can customise and
7//! create a [`RemoteActorSystem`].
8//!
9//! ## Remote-enabled messages
10//! Messages are not available to be handled remotely by default, and do require being registered
11//! with the [`RemoteActorSystem`] during the creation process.
12//!
13//! All message handlers must have a unique identifier assigned.
14//!
15//! ## Builder Example
16//! ```rust
17//! use coerce::actor::system::ActorSystem;
18//! use coerce::remote::system::RemoteActorSystem;
19//!
20//! #[tokio::main]
21//! async fn main() {
22//! let system = ActorSystem::new();
23//! let remote = RemoteActorSystem::builder()
24//! .with_id(1)
25//! .with_tag("node-name")
26//! .with_actor_system(system)
27//! .build()
28//! .await;
29//! }
30//! ```
31//!
32//! ## Registering Remote-enabled Messages
33//! Remote-enabled messages can be enabled when creating a [`RemoteActorSystem`], below is an example
34//! of a message of type `MyMessageType` registered, with the actor that processes the
35//! message as type `MyActorType`.
36//!
37//! Note that a prerequisite for messages to be able to be transmitted remotely is that as part
38//! of defining the message, it must define how to serialise and deserialise to and from a `Vec<u8>`.
39//!
40//! ```rust
41//! use coerce::actor::{Actor, system::ActorSystem};
42//! use coerce::actor::context::ActorContext;
43//! use coerce::actor::message::{Handler, Message, MessageUnwrapErr, MessageWrapErr};
44//! use coerce::remote::system::RemoteActorSystem;
45//! use async_trait::async_trait;
46//!
47//! #[tokio::main]
48//! pub async fn main() {
49//! let system = ActorSystem::new();
50//! let remote_system = RemoteActorSystem::builder()
51//! .with_id(1)
52//! .with_tag("node_name")
53//! .with_actor_system(system)
54//! .with_handlers(|handlers| {
55//! handlers
56//! .with_handler::<MyActor, MyMessage>("MyActor.MyMessage")
57//! });
58//!
59//! // start servers, create actors etc
60//! }
61//!
62//! struct MyActor;
63//!
64//! impl Actor for MyActor { }
65//!
66//! struct MyMessage;
67//!
68//! #[async_trait]
69//! impl Handler<MyMessage> for MyActor {
70//! async fn handle(&mut self, message: MyMessage, ctx: &mut ActorContext) {
71//! // handle the msg
72//! }
73//! }
74//!
75//! impl Message for MyMessage {
76//! type Result = ();
77//!
78//! fn as_bytes(&self) -> Result<Vec<u8>, MessageWrapErr> {
79//! Ok(vec![])
80//! }
81//!
82//! fn from_bytes(_: Vec<u8>) -> Result<Self, MessageUnwrapErr> {
83//! Ok(Self)
84//! }
85//! }
86//! ```
87//!
88//! [`NodeId`]: system::NodeId
89//! [`RemoteActorSystemBuilder`]: system::builder::RemoteActorSystemBuilder
90//! [`RemoteActorSystem`]: system::RemoteActorSystem
91
92pub mod actor;
93pub mod actor_ref;
94pub mod cluster;
95pub mod config;
96pub mod handler;
97pub mod heartbeat;
98pub mod net;
99pub mod stream;
100pub mod system;
101pub mod tracing;
102
103#[cfg(feature = "api")]
104pub mod api;
105
106pub use actor_ref::*;