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
//! # Maiko
//!
//! A topic-based pub/sub actor runtime for Tokio.
//!
//! Maiko helps you build multi-task Tokio applications without manually wiring
//! channels or spawning tasks. Declare actors and subscriptions, and Maiko handles
//! event routing and lifecycle management. Think Kafka-style pub/sub, but embedded
//! in your Tokio application.
//!
//! ## Quick Start
//!
//! ```rust,no_run
//! use maiko::*;
//!
//! #[derive(Event, Clone, Debug)]
//! enum MyEvent {
//! Hello(String),
//! }
//!
//! struct Greeter;
//!
//! impl Actor for Greeter {
//! type Event = MyEvent;
//!
//! async fn handle_event(&mut self, envelope: &Envelope<Self::Event>) -> Result {
//! if let MyEvent::Hello(name) = envelope.event() {
//! println!("Hello, {}!", name);
//! }
//! Ok(())
//! }
//! }
//!
//! #[tokio::main]
//! async fn main() -> Result {
//! let mut sup = Supervisor::<MyEvent>::default();
//! sup.add_actor("greeter", |_ctx| Greeter, &[DefaultTopic])?;
//!
//! sup.start().await?;
//! sup.send(MyEvent::Hello("World".into())).await?;
//! sup.stop().await
//! }
//! ```
//!
//! ## Core Types
//!
//! | Type | Description |
//! |------|-------------|
//! | [`Event`] | Marker trait for event types (use `#[derive(Event)]`) |
//! | [`Actor`] | Trait for implementing actors |
//! | [`Topic`] | Routes events to interested actors |
//! | [`Supervisor`] | Manages actor lifecycles and runtime |
//! | [`Context`] | Allows actors to send events and interact with runtime |
//! | [`Envelope`] | Wraps events with metadata (sender, timestamp, parent ID) |
//! | [`ActorId`] | Unique identifier for a registered actor |
//! | [`OverflowPolicy`] | Controls behavior when a subscriber's channel is full |
//!
//! ## Topic-Based Routing
//!
//! Actors subscribe to topics, and events are automatically routed to all interested subscribers.
//! Use [`DefaultTopic`] when you don't need routing, or implement [`Topic`] for custom filtering:
//!
//! ```rust,ignore
//! #[derive(Debug, Hash, Eq, PartialEq, Clone)]
//! enum MyTopic { Data, Control }
//!
//! impl Topic<MyEvent> for MyTopic {
//! fn from_event(event: &MyEvent) -> Self {
//! match event {
//! MyEvent::Data(_) => MyTopic::Data,
//! MyEvent::Control(_) => MyTopic::Control,
//! }
//! }
//! }
//!
//! sup.add_actor("processor", |ctx| Processor::new(ctx), &[MyTopic::Data])?;
//! ```
//!
//! ## Flow Control
//!
//! Events pass through two channel stages:
//!
//! 1. **Stage 1** (producer to broker) - per-actor channel, always blocks when full
//! 2. **Stage 2** (broker to subscriber) - per-actor channel, governed by [`OverflowPolicy`]
//!
//! Override [`Topic::overflow_policy()`] to control stage 2 behavior per topic:
//!
//! ```rust,ignore
//! fn overflow_policy(&self) -> OverflowPolicy {
//! match self {
//! MyTopic::Data => OverflowPolicy::Block, // wait for space
//! MyTopic::Metrics => OverflowPolicy::Drop, // discard if slow
//! }
//! }
//! ```
//!
//! Producers can check [`Context::is_sender_full()`] to skip non-essential
//! sends when stage 1 is congested:
//!
//! ```rust,ignore
//! if !ctx.is_sender_full() {
//! ctx.send(Event::Telemetry(stats)).await?;
//! }
//! ```
//!
//! See [`OverflowPolicy`] for details on each variant and trade-offs.
//!
//! ## Features
//!
//! - **`macros`** (default) - `#[derive(Event)]`, `#[derive(Label)]`, and `#[derive(SelfRouting)]` macros
//! - **`monitoring`** - Event lifecycle hooks for debugging, metrics, and logging
//! - **`test-harness`** - Test utilities for recording, spying, and asserting on event flow (enables `monitoring`)
//! - **`serde`** - JSON serialization support (e.g. `Supervisor::to_json()`)
//! - **`recorder`** - Built-in `Recorder` monitor for writing events to JSON Lines files (enables `monitoring` and `serde`)
//!
//! ## Examples
//!
//! See the [`examples/`](https://github.com/maiko-rs/maiko/tree/main/maiko/examples) directory:
//!
//! - `pingpong.rs` - Simple event exchange between actors
//! - `guesser.rs` - Multi-actor game with topics and timing
//! - `arbitrage.rs` - Test harness demonstration
pub use Actor;
pub use ActorBuilder;
pub use ActorConfig;
pub use ActorId;
pub use Context;
pub use Envelope;
pub use Error;
pub use Event;
pub use EventId;
pub use IntoEnvelope;
pub use Label;
pub use Meta;
pub use OverflowPolicy;
pub use StepAction;
pub use Subscribe;
pub use Supervisor;
pub use SupervisorConfig;
pub use ;
pub use ;
/// Convenience alias for `Result<T, maiko::Error>`.
pub type Result<T = > = Result;