1use 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#[derive(Debug, Clone, Copy, PartialEq, Eq)]
67pub enum HandlerLane {
68 Sync,
70 Async,
72}
73
74#[derive(Debug, Error)]
76pub enum EventBusError {
77 #[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 #[error("No handlers registered for event type '{event_type}'")]
87 NoHandlers { event_type: String },
88
89 #[error("Failed to subscribe handler: {message}")]
91 SubscriptionFailed { message: String },
92
93 #[error("Event bus error: {message}")]
95 Other { message: String },
96}
97
98impl EventBusError {
99 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 pub fn no_handlers(event_type: impl Into<String>) -> Self {
114 EventBusError::NoHandlers {
115 event_type: event_type.into(),
116 }
117 }
118
119 pub fn subscription_failed(message: impl Into<String>) -> Self {
121 EventBusError::SubscriptionFailed {
122 message: message.into(),
123 }
124 }
125
126 pub fn other(message: impl Into<String>) -> Self {
128 EventBusError::Other {
129 message: message.into(),
130 }
131 }
132}
133
134pub type EventBusResult<T> = Result<T, EventBusError>;
136
137#[async_trait]
174pub trait EventHandler: Send + Sync {
175 fn handles(&self) -> Vec<String>;
184
185 async fn handle(&self, event: &Event) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
205
206 fn lane(&self) -> HandlerLane {
208 HandlerLane::Sync
209 }
210}
211
212#[async_trait]
240pub trait EventBus: Send + Sync {
241 async fn publish(&self, events: Vec<Event>) -> EventBusResult<()>;
270
271 async fn subscribe(&mut self, handler: Box<dyn EventHandler>) -> EventBusResult<()>;
294}
295
296#[derive(Clone)]
349pub struct InProcessEventBus {
350 handlers: Arc<Mutex<Vec<Box<dyn EventHandler>>>>,
351}
352
353impl InProcessEventBus {
354 pub fn new() -> Self {
364 Self {
365 handlers: Arc::new(Mutex::new(Vec::new())),
366 }
367 }
368
369 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 for handler in handlers.iter() {
403 let handled_types = handler.handles();
404
405 if handled_types.contains(&event.event_type) {
406 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#[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 pub fn new() -> Self {
448 Self {
449 sync: InProcessEventBus::new(),
450 async_lane: AsyncLaneEventBus::InProcess(InProcessEventBus::new()),
451 }
452 }
453
454 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 pub async fn sync_handler_count(&self) -> usize {
464 self.sync.handler_count().await
465 }
466
467 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 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 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 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 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 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 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 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 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 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 let bus2 = bus1.clone();
1041
1042 assert_eq!(bus1.handler_count().await, 1);
1044 assert_eq!(bus2.handler_count().await, 1);
1045
1046 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}