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
//! Coerce Remoting
//!
//! Coerce clusters are identified by a [`NodeId`] and a string-based node tag.
//!
//! The easiest way to create a full, batteries-included clustered actor system, is by
//! using the [`RemoteActorSystemBuilder`]. From here, you can customise and
//! create a [`RemoteActorSystem`].
//!
//! ## Remote-enabled messages
//! Messages are not available to be handled remotely by default, and do require being registered
//! with the [`RemoteActorSystem`] during the creation process.
//!
//! All message handlers must have a unique identifier assigned.
//!
//! ## Builder Example
//! ```rust
//! use coerce::actor::system::ActorSystem;
//! use coerce::remote::system::RemoteActorSystem;
//!
//! #[tokio::main]
//! async fn main() {
//! let system = ActorSystem::new();
//! let remote = RemoteActorSystem::builder()
//! .with_id(1)
//! .with_tag("node-name")
//! .with_actor_system(system)
//! .build()
//! .await;
//! }
//! ```
//!
//! ## Registering Remote-enabled Messages
//! Remote-enabled messages can be enabled when creating a [`RemoteActorSystem`], below is an example
//! of a message of type `MyMessageType` registered, with the actor that processes the
//! message as type `MyActorType`.
//!
//! Note that a prerequisite for messages to be able to be transmitted remotely is that as part
//! of defining the message, it must define how to serialise and deserialise to and from a `Vec<u8>`.
//!
//! ```rust
//! use coerce::actor::{Actor, system::ActorSystem};
//! use coerce::actor::context::ActorContext;
//! use coerce::actor::message::{Handler, Message, MessageUnwrapErr, MessageWrapErr};
//! use coerce::remote::system::RemoteActorSystem;
//! use async_trait::async_trait;
//!
//! #[tokio::main]
//! pub async fn main() {
//! let system = ActorSystem::new();
//! let remote_system = RemoteActorSystem::builder()
//! .with_id(1)
//! .with_tag("node_name")
//! .with_actor_system(system)
//! .with_handlers(|handlers| {
//! handlers
//! .with_handler::<MyActor, MyMessage>("MyActor.MyMessage")
//! });
//!
//! // start servers, create actors etc
//! }
//!
//! struct MyActor;
//!
//! impl Actor for MyActor { }
//!
//! struct MyMessage;
//!
//! #[async_trait]
//! impl Handler<MyMessage> for MyActor {
//! async fn handle(&mut self, message: MyMessage, ctx: &mut ActorContext) {
//! // handle the msg
//! }
//! }
//!
//! impl Message for MyMessage {
//! type Result = ();
//!
//! fn as_bytes(&self) -> Result<Vec<u8>, MessageWrapErr> {
//! Ok(vec![])
//! }
//!
//! fn from_bytes(_: Vec<u8>) -> Result<Self, MessageUnwrapErr> {
//! Ok(Self)
//! }
//! }
//! ```
//!
//! [`NodeId`]: system::NodeId
//! [`RemoteActorSystemBuilder`]: system::builder::RemoteActorSystemBuilder
//! [`RemoteActorSystem`]: system::RemoteActorSystem
pub use *;