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