Skip to main content

arc_core/
event_bus.rs

1//! # Event Bus Module
2//!
3//! Defines the EventBus and EventHandler traits for pub/sub event handling.
4//!
5//! ## Design Principles
6//!
7//! - **Decoupled**: Publishers don't know about subscribers
8//! - **Synchronous**: InProcessEventBus handles events synchronously in order
9//! - **Type-safe**: Event handlers declare which event types they handle
10//! - **Extensible**: Multiple handlers can subscribe to the same events
11//!
12//! ## Example
13//!
14//! ```rust
15//! use arc_core::event_bus::{EventBus, EventHandler, InProcessEventBus};
16//! use arc_core::event::Event;
17//! use serde_json::json;
18//! use async_trait::async_trait;
19//!
20//! // Define a custom event handler
21//! struct WelcomeEmailHandler;
22//!
23//! #[async_trait]
24//! impl EventHandler for WelcomeEmailHandler {
25//!     fn handles(&self) -> Vec<String> {
26//!         vec!["UserCreated".to_string()]
27//!     }
28//!
29//!     async fn handle(&self, event: &Event) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
30//!         if event.event_type == "UserCreated" {
31//!             println!("Sending welcome email for user: {}", event.aggregate_id);
32//!         }
33//!         Ok(())
34//!     }
35//! }
36//!
37//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
38//! // Create event bus
39//! let mut event_bus = InProcessEventBus::new();
40//!
41//! // Subscribe handler
42//! event_bus.subscribe(Box::new(WelcomeEmailHandler)).await?;
43//!
44//! // Publish event
45//! let event = Event::new(
46//!     "User",
47//!     "user-123",
48//!     1,
49//!     "UserCreated",
50//!     json!({ "email": "alice@example.com" }),
51//! );
52//! event_bus.publish(vec![event]).await?;
53//! # Ok(())
54//! # }
55//! ```
56
57use crate::event::Event;
58use async_trait::async_trait;
59use std::sync::Arc;
60use thiserror::Error;
61use tokio::sync::Mutex;
62
63/// Delivery lane selected by an [`EventHandler`].
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
65pub enum HandlerLane {
66    /// Runs inline on the caller's publish path. Failure propagates.
67    Sync,
68    /// Runs through an off-path carrier. Failure is logged and does not fail publish.
69    Async,
70}
71
72/// Errors that can occur during event bus operations.
73#[derive(Debug, Error)]
74pub enum EventBusError {
75    /// Handler execution failed
76    #[error("Event handler failed for event '{event_type}' (event_id: {event_id}): {message}")]
77    HandlerFailed {
78        event_type: String,
79        event_id: String,
80        message: String,
81    },
82
83    /// No handlers registered for event type
84    #[error("No handlers registered for event type '{event_type}'")]
85    NoHandlers { event_type: String },
86
87    /// Handler subscription failed
88    #[error("Failed to subscribe handler: {message}")]
89    SubscriptionFailed { message: String },
90
91    /// General event bus error
92    #[error("Event bus error: {message}")]
93    Other { message: String },
94}
95
96impl EventBusError {
97    /// Create a handler failed error.
98    pub fn handler_failed(
99        event_type: impl Into<String>,
100        event_id: impl Into<String>,
101        message: impl Into<String>,
102    ) -> Self {
103        EventBusError::HandlerFailed {
104            event_type: event_type.into(),
105            event_id: event_id.into(),
106            message: message.into(),
107        }
108    }
109
110    /// Create a no handlers error.
111    pub fn no_handlers(event_type: impl Into<String>) -> Self {
112        EventBusError::NoHandlers {
113            event_type: event_type.into(),
114        }
115    }
116
117    /// Create a subscription failed error.
118    pub fn subscription_failed(message: impl Into<String>) -> Self {
119        EventBusError::SubscriptionFailed {
120            message: message.into(),
121        }
122    }
123
124    /// Create a generic error.
125    pub fn other(message: impl Into<String>) -> Self {
126        EventBusError::Other {
127            message: message.into(),
128        }
129    }
130}
131
132/// Result type for event bus operations.
133pub type EventBusResult<T> = Result<T, EventBusError>;
134
135/// Trait for event handlers that process published events.
136///
137/// Event handlers subscribe to specific event types and execute side effects
138/// when those events occur. Handlers should be idempotent where possible.
139///
140/// # Thread Safety
141///
142/// Implementations must be Send + Sync to work with async Rust.
143///
144/// # Example
145///
146/// ```rust
147/// use arc_core::event_bus::EventHandler;
148/// use arc_core::event::Event;
149/// use async_trait::async_trait;
150///
151/// struct AuditLogHandler;
152///
153/// #[async_trait]
154/// impl EventHandler for AuditLogHandler {
155///     fn handles(&self) -> Vec<String> {
156///         // Handle all user-related events
157///         vec![
158///             "UserCreated".to_string(),
159///             "UserUpdated".to_string(),
160///             "UserDeleted".to_string(),
161///         ]
162///     }
163///
164///     async fn handle(&self, event: &Event) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
165///         println!("Audit: {} at {}", event.event_type, event.timestamp);
166///         // Write to audit log...
167///         Ok(())
168///     }
169/// }
170/// ```
171#[async_trait]
172pub trait EventHandler: Send + Sync {
173    /// Returns the list of event types this handler is interested in.
174    ///
175    /// The handler's `handle()` method will only be called for events
176    /// whose event_type is in this list.
177    ///
178    /// # Returns
179    ///
180    /// Vector of event type names (e.g., ["UserCreated", "UserUpdated"])
181    fn handles(&self) -> Vec<String>;
182
183    /// Handle a published event.
184    ///
185    /// This method is called when an event matching one of the types returned
186    /// by `handles()` is published to the event bus.
187    ///
188    /// # Arguments
189    ///
190    /// - `event`: Reference to the event being handled
191    ///
192    /// # Returns
193    ///
194    /// - `Ok(())` if the event was handled successfully
195    /// - `Err(...)` if handling failed (error will be propagated to publisher)
196    ///
197    /// # Error Handling
198    ///
199    /// If an error is returned, it will stop event processing for subsequent
200    /// handlers. Consider logging errors and returning Ok(()) if you want
201    /// to allow other handlers to continue.
202    async fn handle(&self, event: &Event) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
203
204    /// Selects the delivery lane for this handler.
205    fn lane(&self) -> HandlerLane {
206        HandlerLane::Sync
207    }
208}
209
210/// Trait for event bus implementations.
211///
212/// The event bus provides pub/sub functionality for domain events.
213/// Publishers call `publish()` to send events, and subscribers register
214/// via `subscribe()` to receive events they're interested in.
215///
216/// # Thread Safety
217///
218/// Implementations must be Send + Sync to work with async Rust.
219///
220/// # Example
221///
222/// ```rust,ignore
223/// use arc_core::event_bus::{EventBus, InProcessEventBus};
224///
225/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
226/// let mut event_bus = InProcessEventBus::new();
227///
228/// // Subscribe handlers
229/// event_bus.subscribe(Box::new(EmailHandler::new())).await?;
230/// event_bus.subscribe(Box::new(NotificationHandler::new())).await?;
231///
232/// // Publish events
233/// event_bus.publish(events).await?;
234/// # Ok(())
235/// # }
236/// ```
237#[async_trait]
238pub trait EventBus: Send + Sync {
239    /// Publish events to all subscribed handlers.
240    ///
241    /// Events are delivered to all handlers that have registered interest
242    /// in their event_type via the `handles()` method.
243    ///
244    /// # Arguments
245    ///
246    /// - `events`: Vector of events to publish
247    ///
248    /// # Returns
249    ///
250    /// - `Ok(())` if all handlers processed all events successfully
251    /// - `Err(EventBusError::HandlerFailed)` if any handler fails
252    ///
253    /// # Ordering
254    ///
255    /// Events are delivered in the order provided. Handlers are called
256    /// synchronously in subscription order.
257    ///
258    /// # Example
259    ///
260    /// ```rust,ignore
261    /// # async fn example(event_bus: impl EventBus, events: Vec<Event>) -> Result<(), Box<dyn std::error::Error>> {
262    /// // Publish multiple events
263    /// event_bus.publish(events).await?;
264    /// # Ok(())
265    /// # }
266    /// ```
267    async fn publish(&self, events: Vec<Event>) -> EventBusResult<()>;
268
269    /// Subscribe an event handler to the bus.
270    ///
271    /// The handler will be called for all future events that match
272    /// the types returned by its `handles()` method.
273    ///
274    /// # Arguments
275    ///
276    /// - `handler`: Boxed event handler implementation
277    ///
278    /// # Returns
279    ///
280    /// - `Ok(())` if subscription succeeded
281    /// - `Err(EventBusError::SubscriptionFailed)` if subscription failed
282    ///
283    /// # Example
284    ///
285    /// ```rust,ignore
286    /// # async fn example(mut event_bus: impl EventBus) -> Result<(), Box<dyn std::error::Error>> {
287    /// event_bus.subscribe(Box::new(MyHandler::new())).await?;
288    /// # Ok(())
289    /// # }
290    /// ```
291    async fn subscribe(&mut self, handler: Box<dyn EventHandler>) -> EventBusResult<()>;
292}
293
294/// In-process, synchronous event bus implementation.
295///
296/// This is the default event bus implementation that delivers events
297/// synchronously to all registered handlers in the same process.
298///
299/// # Thread Safety
300///
301/// Uses Arc<Mutex<>> internally for thread-safe handler management.
302///
303/// # Performance
304///
305/// - Synchronous delivery means handlers block the publisher
306/// - Handlers are called sequentially in subscription order
307/// - For high-throughput scenarios, consider async/queue-based implementations
308///
309/// # Example
310///
311/// ```rust
312/// use arc_core::event_bus::{EventBus, EventHandler, InProcessEventBus};
313/// use arc_core::event::Event;
314/// use serde_json::json;
315/// use async_trait::async_trait;
316///
317/// struct LogHandler;
318///
319/// #[async_trait]
320/// impl EventHandler for LogHandler {
321///     fn handles(&self) -> Vec<String> {
322///         vec!["UserCreated".to_string()]
323///     }
324///
325///     async fn handle(&self, event: &Event) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
326///         println!("Event logged: {}", event.event_type);
327///         Ok(())
328///     }
329/// }
330///
331/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
332/// let mut bus = InProcessEventBus::new();
333/// bus.subscribe(Box::new(LogHandler)).await?;
334///
335/// let event = Event::new("User", "user-1", 1, "UserCreated", json!({}));
336/// bus.publish(vec![event]).await?;
337/// # Ok(())
338/// # }
339/// ```
340#[derive(Clone)]
341pub struct InProcessEventBus {
342    handlers: Arc<Mutex<Vec<Box<dyn EventHandler>>>>,
343}
344
345impl InProcessEventBus {
346    /// Create a new in-process event bus.
347    ///
348    /// # Example
349    ///
350    /// ```rust
351    /// use arc_core::event_bus::InProcessEventBus;
352    ///
353    /// let bus = InProcessEventBus::new();
354    /// ```
355    pub fn new() -> Self {
356        Self {
357            handlers: Arc::new(Mutex::new(Vec::new())),
358        }
359    }
360
361    /// Get the number of registered handlers.
362    ///
363    /// Useful for testing and diagnostics.
364    ///
365    /// # Example
366    ///
367    /// ```rust
368    /// use arc_core::event_bus::InProcessEventBus;
369    ///
370    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
371    /// let bus = InProcessEventBus::new();
372    /// assert_eq!(bus.handler_count().await, 0);
373    /// # Ok(())
374    /// # }
375    /// ```
376    pub async fn handler_count(&self) -> usize {
377        self.handlers.lock().await.len()
378    }
379}
380
381impl Default for InProcessEventBus {
382    fn default() -> Self {
383        Self::new()
384    }
385}
386
387#[async_trait]
388impl EventBus for InProcessEventBus {
389    async fn publish(&self, events: Vec<Event>) -> EventBusResult<()> {
390        let handlers = self.handlers.lock().await;
391
392        for event in &events {
393            // Find all handlers interested in this event type
394            for handler in handlers.iter() {
395                let handled_types = handler.handles();
396
397                if handled_types.contains(&event.event_type) {
398                    // Call the handler
399                    handler.handle(event).await.map_err(|e| {
400                        EventBusError::handler_failed(
401                            &event.event_type,
402                            event.event_id.to_string(),
403                            e.to_string(),
404                        )
405                    })?;
406                }
407            }
408        }
409
410        Ok(())
411    }
412
413    async fn subscribe(&mut self, handler: Box<dyn EventHandler>) -> EventBusResult<()> {
414        let mut handlers = self.handlers.lock().await;
415        handlers.push(handler);
416        Ok(())
417    }
418}
419
420/// In-process two-lane event bus with synchronous and asynchronous handlers.
421///
422/// Sync-lane handlers run inline and preserve [`InProcessEventBus`] failure and
423/// ordering semantics. Async-lane handlers are handed to a detached in-process
424/// carrier so their failures never propagate to the publisher.
425#[derive(Clone)]
426pub struct TwoLaneEventBus {
427    sync: InProcessEventBus,
428    async_lane: AsyncLaneEventBus,
429}
430
431#[derive(Clone)]
432enum AsyncLaneEventBus {
433    InProcess(InProcessEventBus),
434    External(Arc<dyn EventBus>),
435}
436
437impl TwoLaneEventBus {
438    /// Create a new two-lane event bus.
439    pub fn new() -> Self {
440        Self {
441            sync: InProcessEventBus::new(),
442            async_lane: AsyncLaneEventBus::InProcess(InProcessEventBus::new()),
443        }
444    }
445
446    /// Create a two-lane bus whose async lane uses an external carrier.
447    pub fn with_async_bus(async_bus: Arc<dyn EventBus>) -> Self {
448        Self {
449            sync: InProcessEventBus::new(),
450            async_lane: AsyncLaneEventBus::External(async_bus),
451        }
452    }
453
454    /// Get the number of sync-lane handlers.
455    pub async fn sync_handler_count(&self) -> usize {
456        self.sync.handler_count().await
457    }
458
459    /// Get the number of async-lane handlers.
460    pub async fn async_handler_count(&self) -> usize {
461        match &self.async_lane {
462            AsyncLaneEventBus::InProcess(async_lane) => async_lane.handler_count().await,
463            AsyncLaneEventBus::External(_) => 0,
464        }
465    }
466}
467
468impl Default for TwoLaneEventBus {
469    fn default() -> Self {
470        Self::new()
471    }
472}
473
474#[async_trait]
475impl EventBus for TwoLaneEventBus {
476    async fn publish(&self, events: Vec<Event>) -> EventBusResult<()> {
477        self.sync.publish(events.clone()).await?;
478
479        let async_lane = self.async_lane.clone();
480        match async_lane {
481            AsyncLaneEventBus::InProcess(async_lane) => {
482                let handle = tokio::spawn(async move {
483                    if let Err(error) = async_lane.publish(events).await {
484                        tracing::warn!(error = ?error, "async event handler failed");
485                    }
486                });
487                drop(handle);
488            }
489            AsyncLaneEventBus::External(async_bus) => async_bus.publish(events).await?,
490        }
491
492        Ok(())
493    }
494
495    async fn subscribe(&mut self, handler: Box<dyn EventHandler>) -> EventBusResult<()> {
496        match handler.lane() {
497            HandlerLane::Sync => self.sync.subscribe(handler).await,
498            HandlerLane::Async => match &mut self.async_lane {
499                AsyncLaneEventBus::InProcess(async_lane) => async_lane.subscribe(handler).await,
500                AsyncLaneEventBus::External(_) => Ok(()),
501            },
502        }
503    }
504}
505
506#[cfg(test)]
507mod tests {
508    use super::*;
509    use serde_json::json;
510    use std::sync::Arc;
511    use tokio::sync::Mutex as TokioMutex;
512
513    // Test handler that counts how many times it's called
514    struct CountingHandler {
515        count: Arc<TokioMutex<usize>>,
516        event_types: Vec<String>,
517    }
518
519    impl CountingHandler {
520        fn new(event_types: Vec<String>) -> Self {
521            Self {
522                count: Arc::new(TokioMutex::new(0)),
523                event_types,
524            }
525        }
526    }
527
528    struct LaneCountingHandler {
529        count: Arc<TokioMutex<usize>>,
530        event_types: Vec<String>,
531        lane: HandlerLane,
532    }
533
534    #[async_trait]
535    impl EventHandler for LaneCountingHandler {
536        fn handles(&self) -> Vec<String> {
537            self.event_types.clone()
538        }
539
540        async fn handle(
541            &self,
542            _event: &Event,
543        ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
544            let mut count = self.count.lock().await;
545            *count += 1;
546            Ok(())
547        }
548
549        fn lane(&self) -> HandlerLane {
550            self.lane
551        }
552    }
553
554    #[async_trait]
555    impl EventHandler for CountingHandler {
556        fn handles(&self) -> Vec<String> {
557            self.event_types.clone()
558        }
559
560        async fn handle(
561            &self,
562            _event: &Event,
563        ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
564            let mut count = self.count.lock().await;
565            *count += 1;
566            Ok(())
567        }
568    }
569
570    // Test handler that fails on specific event types
571    struct FailingHandler {
572        fail_on: String,
573    }
574
575    struct LaneFailingHandler {
576        fail_on: String,
577        lane: HandlerLane,
578    }
579
580    #[async_trait]
581    impl EventHandler for FailingHandler {
582        fn handles(&self) -> Vec<String> {
583            vec![self.fail_on.clone()]
584        }
585
586        async fn handle(
587            &self,
588            _event: &Event,
589        ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
590            Err("Intentional test failure".into())
591        }
592    }
593
594    #[async_trait]
595    impl EventHandler for LaneFailingHandler {
596        fn handles(&self) -> Vec<String> {
597            vec![self.fail_on.clone()]
598        }
599
600        async fn handle(
601            &self,
602            _event: &Event,
603        ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
604            Err("Intentional test failure".into())
605        }
606
607        fn lane(&self) -> HandlerLane {
608            self.lane
609        }
610    }
611
612    #[tokio::test]
613    async fn test_new_event_bus() {
614        let bus = InProcessEventBus::new();
615        assert_eq!(bus.handler_count().await, 0);
616    }
617
618    #[tokio::test]
619    async fn test_subscribe_handler() {
620        let mut bus = InProcessEventBus::new();
621        let handler = Box::new(CountingHandler::new(vec!["UserCreated".to_string()]));
622
623        bus.subscribe(handler).await.unwrap();
624        assert_eq!(bus.handler_count().await, 1);
625    }
626
627    #[tokio::test]
628    async fn test_subscribe_multiple_handlers() {
629        let mut bus = InProcessEventBus::new();
630
631        bus.subscribe(Box::new(CountingHandler::new(vec![
632            "UserCreated".to_string()
633        ])))
634        .await
635        .unwrap();
636        bus.subscribe(Box::new(CountingHandler::new(vec![
637            "UserUpdated".to_string()
638        ])))
639        .await
640        .unwrap();
641
642        assert_eq!(bus.handler_count().await, 2);
643    }
644
645    #[tokio::test]
646    async fn test_publish_single_event() {
647        let mut bus = InProcessEventBus::new();
648        let counter = Arc::new(TokioMutex::new(0));
649        let counter_clone = counter.clone();
650
651        let handler = CountingHandler {
652            count: counter_clone,
653            event_types: vec!["UserCreated".to_string()],
654        };
655
656        bus.subscribe(Box::new(handler)).await.unwrap();
657
658        let event = Event::new(
659            "User",
660            "user-123",
661            1,
662            "UserCreated",
663            json!({ "name": "Alice" }),
664        );
665
666        bus.publish(vec![event]).await.unwrap();
667
668        let count = *counter.lock().await;
669        assert_eq!(count, 1);
670    }
671
672    #[tokio::test]
673    async fn test_publish_multiple_events() {
674        let mut bus = InProcessEventBus::new();
675        let counter = Arc::new(TokioMutex::new(0));
676        let counter_clone = counter.clone();
677
678        let handler = CountingHandler {
679            count: counter_clone,
680            event_types: vec!["UserCreated".to_string(), "UserUpdated".to_string()],
681        };
682
683        bus.subscribe(Box::new(handler)).await.unwrap();
684
685        let events = vec![
686            Event::new(
687                "User",
688                "user-1",
689                1,
690                "UserCreated",
691                json!({ "name": "Alice" }),
692            ),
693            Event::new(
694                "User",
695                "user-1",
696                2,
697                "UserUpdated",
698                json!({ "name": "Alice Smith" }),
699            ),
700            Event::new("User", "user-2", 1, "UserCreated", json!({ "name": "Bob" })),
701        ];
702
703        bus.publish(events).await.unwrap();
704
705        let count = *counter.lock().await;
706        assert_eq!(count, 3);
707    }
708
709    #[tokio::test]
710    async fn test_handler_filters_event_types() {
711        let mut bus = InProcessEventBus::new();
712        let counter = Arc::new(TokioMutex::new(0));
713        let counter_clone = counter.clone();
714
715        // Handler only interested in UserCreated
716        let handler = CountingHandler {
717            count: counter_clone,
718            event_types: vec!["UserCreated".to_string()],
719        };
720
721        bus.subscribe(Box::new(handler)).await.unwrap();
722
723        let events = vec![
724            Event::new("User", "user-1", 1, "UserCreated", json!({})),
725            Event::new("User", "user-1", 2, "UserUpdated", json!({})),
726            Event::new("User", "user-1", 3, "UserDeleted", json!({})),
727        ];
728
729        bus.publish(events).await.unwrap();
730
731        // Should only count UserCreated event
732        let count = *counter.lock().await;
733        assert_eq!(count, 1);
734    }
735
736    #[tokio::test]
737    async fn test_multiple_handlers_same_event() {
738        let mut bus = InProcessEventBus::new();
739        let counter1 = Arc::new(TokioMutex::new(0));
740        let counter2 = Arc::new(TokioMutex::new(0));
741
742        let handler1 = CountingHandler {
743            count: counter1.clone(),
744            event_types: vec!["UserCreated".to_string()],
745        };
746
747        let handler2 = CountingHandler {
748            count: counter2.clone(),
749            event_types: vec!["UserCreated".to_string()],
750        };
751
752        bus.subscribe(Box::new(handler1)).await.unwrap();
753        bus.subscribe(Box::new(handler2)).await.unwrap();
754
755        let event = Event::new("User", "user-1", 1, "UserCreated", json!({}));
756        bus.publish(vec![event]).await.unwrap();
757
758        // Both handlers should be called
759        assert_eq!(*counter1.lock().await, 1);
760        assert_eq!(*counter2.lock().await, 1);
761    }
762
763    #[tokio::test]
764    async fn test_handler_failure_propagates() {
765        let mut bus = InProcessEventBus::new();
766
767        let failing_handler = Box::new(FailingHandler {
768            fail_on: "UserCreated".to_string(),
769        });
770
771        bus.subscribe(failing_handler).await.unwrap();
772
773        let event = Event::new("User", "user-1", 1, "UserCreated", json!({}));
774        let result = bus.publish(vec![event]).await;
775
776        assert!(result.is_err());
777        match result.unwrap_err() {
778            EventBusError::HandlerFailed {
779                event_type,
780                event_id,
781                message,
782            } => {
783                assert_eq!(event_type, "UserCreated");
784                assert!(!event_id.is_empty());
785                assert!(message.contains("Intentional test failure"));
786            }
787            _ => panic!("Expected HandlerFailed error"),
788        }
789    }
790
791    #[tokio::test]
792    async fn test_event_handler_default_lane_is_sync() {
793        let handler = CountingHandler::new(vec!["UserCreated".to_string()]);
794
795        assert_eq!(handler.lane(), HandlerLane::Sync);
796    }
797
798    #[tokio::test]
799    async fn test_two_lane_sync_handler_failure_propagates() {
800        let mut bus = TwoLaneEventBus::new();
801
802        bus.subscribe(Box::new(LaneFailingHandler {
803            fail_on: "UserCreated".to_string(),
804            lane: HandlerLane::Sync,
805        }))
806        .await
807        .unwrap();
808
809        let event = Event::new("User", "user-1", 1, "UserCreated", json!({}));
810        let result = bus.publish(vec![event]).await;
811
812        assert!(matches!(result, Err(EventBusError::HandlerFailed { .. })));
813    }
814
815    #[tokio::test]
816    async fn test_two_lane_async_handler_failure_does_not_propagate() {
817        let mut bus = TwoLaneEventBus::new();
818
819        bus.subscribe(Box::new(LaneFailingHandler {
820            fail_on: "UserCreated".to_string(),
821            lane: HandlerLane::Async,
822        }))
823        .await
824        .unwrap();
825
826        let event = Event::new("User", "user-1", 1, "UserCreated", json!({}));
827        let result = bus.publish(vec![event]).await;
828
829        assert!(result.is_ok());
830    }
831
832    #[tokio::test]
833    async fn test_two_lane_routes_handlers_by_lane() {
834        let mut bus = TwoLaneEventBus::new();
835        let sync_count = Arc::new(TokioMutex::new(0));
836        let async_count = Arc::new(TokioMutex::new(0));
837
838        bus.subscribe(Box::new(LaneCountingHandler {
839            count: sync_count,
840            event_types: vec!["UserCreated".to_string()],
841            lane: HandlerLane::Sync,
842        }))
843        .await
844        .unwrap();
845        bus.subscribe(Box::new(LaneCountingHandler {
846            count: async_count,
847            event_types: vec!["UserCreated".to_string()],
848            lane: HandlerLane::Async,
849        }))
850        .await
851        .unwrap();
852
853        assert_eq!(bus.sync_handler_count().await, 1);
854        assert_eq!(bus.async_handler_count().await, 1);
855    }
856
857    #[tokio::test]
858    async fn test_no_handlers_for_event_type() {
859        let bus = InProcessEventBus::new();
860
861        // No handlers subscribed
862        let event = Event::new("User", "user-1", 1, "UserCreated", json!({}));
863        let result = bus.publish(vec![event]).await;
864
865        // Should succeed - no handlers is not an error
866        assert!(result.is_ok());
867    }
868
869    #[tokio::test]
870    async fn test_handler_called_in_order() {
871        let mut bus = InProcessEventBus::new();
872        let order = Arc::new(TokioMutex::new(Vec::new()));
873
874        struct OrderTracker {
875            id: usize,
876            order: Arc<TokioMutex<Vec<usize>>>,
877        }
878
879        #[async_trait]
880        impl EventHandler for OrderTracker {
881            fn handles(&self) -> Vec<String> {
882                vec!["TestEvent".to_string()]
883            }
884
885            async fn handle(
886                &self,
887                _event: &Event,
888            ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
889                self.order.lock().await.push(self.id);
890                Ok(())
891            }
892        }
893
894        // Subscribe 3 handlers
895        for i in 1..=3 {
896            bus.subscribe(Box::new(OrderTracker {
897                id: i,
898                order: order.clone(),
899            }))
900            .await
901            .unwrap();
902        }
903
904        let event = Event::new("Test", "test-1", 1, "TestEvent", json!({}));
905        bus.publish(vec![event]).await.unwrap();
906
907        // Handlers should be called in subscription order
908        let call_order = order.lock().await;
909        assert_eq!(*call_order, vec![1, 2, 3]);
910    }
911
912    #[tokio::test]
913    async fn test_two_lane_sync_handlers_called_in_order() {
914        let mut bus = TwoLaneEventBus::new();
915        let order = Arc::new(TokioMutex::new(Vec::new()));
916
917        struct OrderTracker {
918            id: usize,
919            order: Arc<TokioMutex<Vec<usize>>>,
920        }
921
922        #[async_trait]
923        impl EventHandler for OrderTracker {
924            fn handles(&self) -> Vec<String> {
925                vec!["TestEvent".to_string()]
926            }
927
928            async fn handle(
929                &self,
930                _event: &Event,
931            ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
932                self.order.lock().await.push(self.id);
933                Ok(())
934            }
935        }
936
937        for i in 1..=3 {
938            bus.subscribe(Box::new(OrderTracker {
939                id: i,
940                order: order.clone(),
941            }))
942            .await
943            .unwrap();
944        }
945
946        let event = Event::new("Test", "test-1", 1, "TestEvent", json!({}));
947        bus.publish(vec![event]).await.unwrap();
948
949        let call_order = order.lock().await;
950        assert_eq!(*call_order, vec![1, 2, 3]);
951    }
952
953    #[tokio::test]
954    async fn test_event_bus_clone() {
955        let mut bus1 = InProcessEventBus::new();
956        let counter = Arc::new(TokioMutex::new(0));
957
958        let handler = CountingHandler {
959            count: counter.clone(),
960            event_types: vec!["UserCreated".to_string()],
961        };
962
963        bus1.subscribe(Box::new(handler)).await.unwrap();
964
965        // Clone the bus
966        let bus2 = bus1.clone();
967
968        // Both should share the same handlers
969        assert_eq!(bus1.handler_count().await, 1);
970        assert_eq!(bus2.handler_count().await, 1);
971
972        // Publishing through either should work
973        let event = Event::new("User", "user-1", 1, "UserCreated", json!({}));
974        bus2.publish(vec![event]).await.unwrap();
975
976        assert_eq!(*counter.lock().await, 1);
977    }
978
979    #[test]
980    fn test_error_messages() {
981        let error = EventBusError::handler_failed("UserCreated", "event-123", "Connection timeout");
982        let msg = error.to_string();
983        assert!(msg.contains("UserCreated"));
984        assert!(msg.contains("event-123"));
985        assert!(msg.contains("Connection timeout"));
986
987        let error = EventBusError::no_handlers("UnknownEvent");
988        assert!(error.to_string().contains("UnknownEvent"));
989
990        let error = EventBusError::subscription_failed("Handler invalid");
991        assert!(error.to_string().contains("Handler invalid"));
992    }
993}