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 pub fn subscribe(&self) -> broadcast::Receiver<Event> {
39 self.sender.subscribe()
40 }
41
42 /// Emit an event to all broadcast receivers and all registered subscribers.
43 /// If there are no broadcast receivers, the send is silently dropped.
44 pub async fn emit(&self, event: Event) {
45 // Notify synchronous subscribers
46 for sub in &self.subscribers {
47 sub.on_event(&event);
48 }
49
50 // Broadcast to async receivers; ignore errors (no receivers = ok)
51 let _ = self.sender.send(event);
52 }
53
54 /// Register a synchronous subscriber that will be called for every event.
55 pub fn add_subscriber(&mut self, subscriber: Box<dyn EventSubscriber + Send + Sync>) {
56 self.subscribers.push(subscriber);
57 }
58}
59
60impl Default for EventBus {
61 fn default() -> Self {
62 Self::new()
63 }
64}