Skip to main content

reifydb_core/event/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use std::{
5	any::{Any, TypeId, type_name},
6	collections::HashMap,
7	sync,
8	sync::Arc,
9};
10
11use reifydb_runtime::actor::{
12	context::Context,
13	mailbox::ActorRef,
14	system::ActorSpawner,
15	traits::{Actor, Directive},
16};
17use sync::mpsc::Sender;
18
19pub mod lifecycle;
20pub mod operator;
21#[macro_use]
22pub mod r#macro;
23pub mod metric;
24pub mod procedure;
25pub mod row;
26pub mod store;
27pub mod transaction;
28
29type EventListenerInstaller = Box<dyn FnOnce(&mut HashMap<TypeId, Box<dyn EventListenerList>>) + Send>;
30
31pub trait Event: Any + Send + Sync + Clone + 'static {
32	fn as_any(&self) -> &dyn Any;
33	fn into_any(self) -> Box<dyn Any + Send>;
34}
35
36pub trait EventListener<E>: Send + Sync + 'static
37where
38	E: Event,
39{
40	fn on(&self, event: &E);
41}
42
43trait EventListenerList: Any + Send + Sync {
44	fn on_any(&self, event: Box<dyn Any + Send>);
45	fn as_any_mut(&mut self) -> &mut dyn Any;
46}
47
48struct EventListenerListImpl<E> {
49	listeners: Vec<Arc<dyn EventListener<E>>>,
50}
51
52impl<E> EventListenerListImpl<E>
53where
54	E: Event,
55{
56	fn new() -> Self {
57		Self {
58			listeners: Vec::new(),
59		}
60	}
61
62	fn add(&mut self, listener: Arc<dyn EventListener<E>>) {
63		self.listeners.push(listener);
64	}
65}
66
67impl<E> EventListenerList for EventListenerListImpl<E>
68where
69	E: Event,
70{
71	fn on_any(&self, event: Box<dyn Any + Send>) {
72		if let Ok(event) = event.downcast::<E>() {
73			for listener in &self.listeners {
74				listener.on(&*event);
75			}
76		}
77	}
78
79	fn as_any_mut(&mut self) -> &mut dyn Any {
80		self
81	}
82}
83
84struct EventEnvelope {
85	type_id: TypeId,
86	event: Box<dyn Any + Send>,
87}
88
89enum EventBusMessage {
90	Emit(EventEnvelope),
91	Register {
92		installer: EventListenerInstaller,
93	},
94	WaitForCompletion(Sender<()>),
95}
96
97struct EventBusActor;
98
99impl Actor for EventBusActor {
100	type State = HashMap<TypeId, Box<dyn EventListenerList>>;
101	type Message = EventBusMessage;
102
103	fn init(&self, _ctx: &Context<Self::Message>) -> Self::State {
104		HashMap::new()
105	}
106
107	fn handle(&self, state: &mut Self::State, msg: Self::Message, _ctx: &Context<Self::Message>) -> Directive {
108		match msg {
109			EventBusMessage::Emit(envelope) => {
110				if let Some(list) = state.get(&envelope.type_id) {
111					list.on_any(envelope.event);
112				}
113			}
114			EventBusMessage::Register {
115				installer,
116			} => {
117				installer(state);
118			}
119			EventBusMessage::WaitForCompletion(tx) => {
120				let _ = tx.send(());
121			}
122		}
123		Directive::Continue
124	}
125}
126
127#[derive(Clone)]
128pub struct EventBus {
129	actor_ref: ActorRef<EventBusMessage>,
130	spawner: ActorSpawner,
131}
132
133impl EventBus {
134	pub fn new(spawner: &ActorSpawner) -> Self {
135		let handle = spawner.spawn_coordination("event-bus", EventBusActor);
136		Self {
137			actor_ref: handle.actor_ref().clone(),
138			spawner: spawner.clone(),
139		}
140	}
141
142	pub fn register<E, L>(&self, listener: L)
143	where
144		E: Event,
145		L: EventListener<E>,
146	{
147		let type_id = TypeId::of::<E>();
148		let listener = Arc::new(listener);
149
150		let installer: EventListenerInstaller = Box::new(move |map| {
151			let list = map.entry(type_id).or_insert_with(|| Box::new(EventListenerListImpl::<E>::new()));
152			list.as_any_mut().downcast_mut::<EventListenerListImpl<E>>().unwrap().add(listener);
153		});
154
155		if self.actor_ref
156			.send(EventBusMessage::Register {
157				installer,
158			})
159			.is_err()
160		{
161			let shutting_down = self.spawner.cancellation_token().is_none_or(|token| token.is_cancelled());
162			assert!(
163				shutting_down,
164				"the event bus rejected a listener for {} while the system was running; the \
165				 listener would never install and every later event of this type is lost silently",
166				type_name::<E>()
167			);
168		}
169	}
170
171	pub fn emit<E>(&self, event: E)
172	where
173		E: Event,
174	{
175		let type_id = TypeId::of::<E>();
176		if self.actor_ref
177			.send(EventBusMessage::Emit(EventEnvelope {
178				type_id,
179				event: event.into_any(),
180			}))
181			.is_err()
182		{
183			let shutting_down = self.spawner.cancellation_token().is_none_or(|token| token.is_cancelled());
184			assert!(
185				shutting_down,
186				"the event bus rejected a {} while the system was running; dropping it silently \
187				 loses a post-commit update no subscriber will ever see",
188				type_name::<E>()
189			);
190		}
191	}
192
193	/// Waits until the bus has drained everything queued ahead of this call.
194	///
195	/// Under dst the caller's thread is also the thread that steps the actor system, so it drives
196	/// the system to quiescence itself and then picks the reply up without blocking. A blocking
197	/// receive here would park the only thread that can run the bus actor, so the reply it waits
198	/// for could never be sent; that deadlocks subsystem start-up before any test can run.
199	#[cfg(reifydb_dst)]
200	pub fn wait_for_completion(&self) {
201		let (tx, rx) = sync::mpsc::channel();
202		if self.actor_ref.send(EventBusMessage::WaitForCompletion(tx)).is_err() {
203			return;
204		}
205		if self.spawner.is_alive() {
206			self.spawner.system().run_until_idle();
207		}
208		let _ = rx.try_recv();
209	}
210
211	/// Waits until the bus has drained everything queued ahead of this call.
212	///
213	/// Off dst the bus actor runs on its own thread (host) or inline on `send` (wasm), so a
214	/// blocking receive is both correct and the cheapest way to wait.
215	#[cfg(not(reifydb_dst))]
216	pub fn wait_for_completion(&self) {
217		let (tx, rx) = sync::mpsc::channel();
218		let _ = self.actor_ref.send(EventBusMessage::WaitForCompletion(tx));
219		let _ = rx.recv();
220	}
221}
222
223#[cfg(test)]
224pub mod tests {
225	use std::{sync::Arc, thread};
226
227	use reifydb_runtime::{
228		actor::system::ActorSystem,
229		context::clock::Clock,
230		pool::{PoolConfig, Pools},
231		sync::mutex::Mutex,
232	};
233
234	use crate::event::{Event, EventBus, EventListener};
235
236	fn test_actor_system() -> ActorSystem {
237		let pools = Pools::new(PoolConfig::default());
238		ActorSystem::new(pools, Clock::Real)
239	}
240
241	define_event! {
242		pub struct TestEvent{}
243	}
244
245	define_event! {
246		pub struct AnotherEvent{}
247	}
248
249	#[derive(Default, Debug, Clone)]
250	pub struct TestEventListener(Arc<TestHandlerInner>);
251
252	#[derive(Default, Debug)]
253	pub struct TestHandlerInner {
254		pub counter: Arc<Mutex<i32>>,
255	}
256
257	impl EventListener<TestEvent> for TestEventListener {
258		fn on(&self, _event: &TestEvent) {
259			let mut x = self.0.counter.lock();
260			*x += 1;
261		}
262	}
263
264	impl EventListener<AnotherEvent> for TestEventListener {
265		fn on(&self, _event: &AnotherEvent) {
266			let mut x = self.0.counter.lock();
267			*x *= 2;
268		}
269	}
270
271	#[test]
272	fn test_event_bus_new() {
273		let actor_system = test_actor_system();
274		let event_bus = EventBus::new(&actor_system.spawner());
275		event_bus.emit(TestEvent::new());
276		event_bus.wait_for_completion();
277	}
278
279	#[test]
280	fn test_register_single_listener() {
281		let actor_system = test_actor_system();
282		let event_bus = EventBus::new(&actor_system.spawner());
283		let listener = TestEventListener::default();
284
285		event_bus.register::<TestEvent, TestEventListener>(listener.clone());
286		event_bus.emit(TestEvent::new());
287		event_bus.wait_for_completion();
288		assert_eq!(*listener.0.counter.lock(), 1);
289	}
290
291	#[test]
292	fn test_emit_unregistered_event() {
293		let actor_system = test_actor_system();
294		let event_bus = EventBus::new(&actor_system.spawner());
295		event_bus.emit(TestEvent::new());
296		event_bus.wait_for_completion();
297	}
298
299	#[test]
300	fn test_multiple_listeners_same_event() {
301		let actor_system = test_actor_system();
302		let event_bus = EventBus::new(&actor_system.spawner());
303		let listener1 = TestEventListener::default();
304		let listener2 = TestEventListener::default();
305
306		event_bus.register::<TestEvent, TestEventListener>(listener1.clone());
307		event_bus.register::<TestEvent, TestEventListener>(listener2.clone());
308
309		event_bus.emit(TestEvent::new());
310		event_bus.wait_for_completion();
311		assert_eq!(*listener1.0.counter.lock(), 1);
312		assert_eq!(*listener2.0.counter.lock(), 1);
313	}
314
315	#[test]
316	fn test_event_bus_clone() {
317		let actor_system = test_actor_system();
318		let event_bus1 = EventBus::new(&actor_system.spawner());
319		let listener = TestEventListener::default();
320		event_bus1.register::<TestEvent, TestEventListener>(listener.clone());
321
322		let event_bus2 = event_bus1.clone();
323		event_bus2.emit(TestEvent::new());
324		event_bus2.wait_for_completion();
325		assert_eq!(*listener.0.counter.lock(), 1);
326	}
327
328	#[test]
329	fn test_concurrent_registration() {
330		let actor_system = test_actor_system();
331		let event_bus = Arc::new(EventBus::new(&actor_system.spawner()));
332		let mut handles = Vec::new();
333
334		for _ in 0..10 {
335			let event_bus = event_bus.clone();
336			handles.push(thread::spawn(move || {
337				let listener = TestEventListener::default();
338				event_bus.register::<TestEvent, TestEventListener>(listener);
339			}));
340		}
341
342		for handle in handles {
343			handle.join().unwrap();
344		}
345
346		event_bus.emit(TestEvent::new());
347		event_bus.wait_for_completion();
348	}
349
350	#[test]
351	fn test_concurrent_emitting() {
352		let actor_system = test_actor_system();
353		let event_bus = Arc::new(EventBus::new(&actor_system.spawner()));
354		let listener = TestEventListener::default();
355		event_bus.register::<TestEvent, TestEventListener>(listener.clone());
356		event_bus.wait_for_completion();
357
358		let mut handles = Vec::new();
359
360		for _ in 0..10 {
361			let event_bus = event_bus.clone();
362			handles.push(thread::spawn(move || {
363				event_bus.emit(TestEvent::new());
364			}));
365		}
366
367		for handle in handles {
368			handle.join().unwrap();
369		}
370
371		event_bus.wait_for_completion();
372		assert_eq!(*listener.0.counter.lock(), 10);
373	}
374
375	define_event! {
376		pub struct MacroTestEvent {
377			pub value: i32,
378		}
379	}
380
381	#[test]
382	fn testine_event_macro() {
383		let event = MacroTestEvent::new(42);
384		let any_ref = event.as_any();
385		assert!(any_ref.downcast_ref::<MacroTestEvent>().is_some());
386		assert_eq!(any_ref.downcast_ref::<MacroTestEvent>().unwrap().value(), &42);
387	}
388
389	#[test]
390	fn test_multi_event_listener() {
391		let actor_system = test_actor_system();
392		let event_bus = EventBus::new(&actor_system.spawner());
393		let listener = TestEventListener::default();
394
395		event_bus.register::<TestEvent, TestEventListener>(listener.clone());
396		event_bus.register::<AnotherEvent, TestEventListener>(listener.clone());
397
398		// Each event type triggers only its own listeners
399		event_bus.emit(TestEvent::new());
400		event_bus.wait_for_completion();
401		assert_eq!(*listener.0.counter.lock(), 1);
402
403		event_bus.emit(TestEvent::new());
404		event_bus.wait_for_completion();
405		assert_eq!(*listener.0.counter.lock(), 2);
406
407		event_bus.emit(AnotherEvent::new());
408		event_bus.wait_for_completion();
409		assert_eq!(*listener.0.counter.lock(), 4); // 2 * 2
410	}
411}