minion_engine/events/mod.rs
1pub mod subscribers;
2pub mod types;
3
4use tokio::sync::broadcast;
5
6pub use types::Event;
7
8/// Capacity of the broadcast channel (number of events buffered before slow
9/// receivers start lagging)
10const CHANNEL_CAPACITY: usize = 256;
11
12/// Trait for synchronous event subscribers that receive a callback on each event.
13pub trait EventSubscriber: Send + Sync {
14 fn on_event(&self, event: &Event);
15}
16
17/// Central event bus used by the engine to publish lifecycle events.
18///
19/// Internally uses a `tokio::sync::broadcast` channel so that multiple
20/// independent async receivers can each consume every event.
21pub struct EventBus {
22 sender: broadcast::Sender<Event>,
23 subscribers: Vec<Box<dyn EventSubscriber + Send + Sync>>,
24}
25
26impl EventBus {
27 /// Create a new EventBus with an empty subscriber list.
28 pub fn new() -> Self {
29 let (sender, _) = broadcast::channel(CHANNEL_CAPACITY);
30 Self {
31 sender,
32 subscribers: Vec::new(),
33 }
34 }
35
36 /// Subscribe to the broadcast channel and receive a `Receiver` handle.
37 /// Multiple handles can be created; each will receive every future event.
38 #[allow(dead_code)]
39 pub fn subscribe(&self) -> broadcast::Receiver<Event> {
40 self.sender.subscribe()
41 }
42
43 /// Emit an event to all broadcast receivers and all registered subscribers.
44 /// If there are no broadcast receivers, the send is silently dropped.
45 pub async fn emit(&self, event: Event) {
46 // Notify synchronous subscribers
47 for sub in &self.subscribers {
48 sub.on_event(&event);
49 }
50
51 // Broadcast to async receivers; ignore errors (no receivers = ok)
52 let _ = self.sender.send(event);
53 }
54
55 /// Register a synchronous subscriber that will be called for every event.
56 pub fn add_subscriber(&mut self, subscriber: Box<dyn EventSubscriber + Send + Sync>) {
57 self.subscribers.push(subscriber);
58 }
59}
60
61impl Default for EventBus {
62 fn default() -> Self {
63 Self::new()
64 }
65}