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
use fmt;
/// Controls what happens when a subscriber's channel is full.
///
/// Events flow through two stages: producers send to the broker (stage 1),
/// and the broker dispatches to subscriber channels (stage 2). Overflow
/// policy governs stage 2 - what the broker does when a specific subscriber
/// can't keep up.
///
/// The policy is defined on [`Topic`](crate::Topic), not on actors, because
/// flow semantics are properties of the data: a critical command topic
/// needs different handling than expendable telemetry, regardless of which
/// actor consumes it.
///
/// # Policies
///
/// | Policy | On full channel | Use case |
/// |--------|----------------|----------|
/// | [`Drop`](Self::Drop) | Discard the event, continue | Telemetry, metrics, status updates |
/// | [`Block`](Self::Block) | Wait for space | Commands, data that must arrive |
/// | [`Fail`](Self::Fail) | Close the subscriber's channel | Real-time topics where stale data is worse than no actor |
///
/// # Default
///
/// The default policy is `Fail`, which ensures overflow is never silent.
/// If a subscriber can't keep up, the system surfaces the problem
/// immediately rather than hiding it behind dropped events. Override
/// [`Topic::overflow_policy()`](crate::Topic::overflow_policy)
/// to choose per-topic behavior.
///
/// # Single-broker limitation
///
/// With a single broker (current architecture), `Block` on one topic
/// delays dispatch to all other topics while the broker waits for space.
/// For most systems (tens to hundreds of actors, moderate event rates)
/// this delay is acceptable. Multi-broker support (planned) eliminates
/// this by giving each topic group its own broker.
///
/// # Example
///
/// ```rust
/// # use maiko::*;
/// # #[derive(Clone, Debug, Event)]
/// # enum MyEvent { Control, Telemetry }
/// # #[derive(Debug, Hash, Eq, PartialEq, Clone)]
/// # enum MyTopic { Control, Telemetry }
/// impl Topic<MyEvent> for MyTopic {
/// fn from_event(event: &MyEvent) -> Self {
/// match event {
/// MyEvent::Control => MyTopic::Control,
/// MyEvent::Telemetry => MyTopic::Telemetry,
/// }
/// }
///
/// fn overflow_policy(&self) -> OverflowPolicy {
/// match self {
/// MyTopic::Control => OverflowPolicy::Block,
/// MyTopic::Telemetry => OverflowPolicy::Drop,
/// }
/// }
/// }
/// ```