Feat/rabbitmq masstransit async events implementation#46
Merged
Rashed99Azm merged 7 commits intoJun 9, 2026
Merged
Conversation
…lly work
The RabbitMQ/MassTransit branch had a sound topology (APIs publish-only →
EF transactional outbox → CCE.Worker consumes) but the runtime path was
broken and inconsistent. This wires it end-to-end and unifies event
emission on a single Clean-Architecture pattern.
Blocker
- DomainEventDispatcher and AuditingInterceptor were registered only as
concrete types, so `AddInterceptors(sp.GetServices<IInterceptor>())`
never attached them — domain events never dispatched and audit columns
stopped writing. Register both as IInterceptor so they attach (alongside
MassTransit's outbox interceptor).
Unify on aggregate → domain event → bridge → outbox → consumer
- Add domain events PostVotedEvent, ReplyCreatedEvent,
CommunityJoinRequestedEvent and the aggregate methods that raise them
(Post.RegisterVote, Post.RegisterReply, Community.RegisterJoinRequest).
- Add bridge handlers (PostVoted/ReplyCreated/CommunityJoinRequested
BusPublisher) that translate domain events to integration events
pre-commit, so the publish is captured atomically by the EF outbox.
- Command handlers (VotePost, CreateReply, JoinCommunity, FollowUser,
UnfollowUser) no longer inject IIntegrationEventPublisher. This removes
the lost-message bug where Join/Follow/Unfollow published AFTER
SaveChanges (outbox row never persisted) and the random-GUID mismatch in
the join-request event.
- Fix MassTransitIntegrationEventPublisher to use IPublishEndpoint (the
non-existent IScopedBusContextProvider<> meant the branch didn't compile).
Realtime (hybrid, deduped)
- VoteConsumer no longer pushes VoteChanged (the API handler owns the
instant push); it keeps only the Redis hot-counter update.
- Remove the dead ICommunityRealtimePublisher injection from CreatePost.
Move work off the API thread + cleanup
- PostCreated notification fan-out now runs in NotificationConsumer
(Worker); delete PostCreatedNotificationHandler.
- Carry the real join-request id and the post Locale on the integration
events.
- Remove unconsumed dead contracts (UserFollowed, UserUnfollowed,
ResourcePublished) and their inline publishing.
Tests + docs
- Add CommunityIntegrationEventConsumerHarnessTests (broker-free MassTransit
harness): VoteCreated→VoteConsumer, PostCreated→NotificationConsumer
(fan-out + Locale), PostCreated→SignalRConsumer.
- Add docs/community-async-events-guide.md and document the canonical
pattern in docs/masstransit-messaging-guide.md.
Verified: solution builds clean; Domain 320/320; new harness tests 3/3;
Application_does_not_depend_on_Infrastructure passes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Event-Driven Infrastructure — MassTransit, RabbitMQ, Redis Outbox & SignalR
Overview
This PR introduces a complete event-driven messaging infrastructure built on MassTransit, RabbitMQ, Redis, and SignalR. The implementation provides reliable asynchronous communication, transactional message delivery through the EF Core Outbox pattern, distributed real-time notifications, and Redis-backed feed/presence management.
The architecture supports both production and local development environments through configurable transport providers:
RabbitMQ for production deployments
MassTransit InMemory Transport for local development and testing
EF Core Transactional Outbox for reliable event delivery
Redis SignalR Backplane for multi-instance scale-out
SignalR for real-time client communication
Architecture
Event Flow
Domain aggregates raise domain events.
Events are captured during EF Core save operations.
Application handlers translate domain events into integration events.
Integration events are stored in the EF Core Outbox within the same transaction.
After successful commit, MassTransit delivers messages to the configured transport.
Consumers process events and update feeds, leaderboards, notifications, and real-time clients.
Added Components
MassTransit + EF Core Outbox
Namespace:
CCE.Infrastructure.Notifications.MessagingFeatures
Centralized MassTransit registration via
MessagingServiceExtensionsEF Core transactional outbox support
Atomic message persistence and delivery
Inbox/Outbox state tracking
Automatic relay through
BusOutboxDeliveryServiceConfigurable transport selection
RabbitMQ availability probe with optional fallback
Database Objects
Migration:
Tables:
Integration Events
Namespace:
Added events:
PostCreatedIntegrationEventVoteCreatedIntegrationEventReplyCreatedIntegrationEventCommunityJoinRequestedIntegrationEventBridge handlers convert domain events into integration events for asynchronous processing.
Consumers
Hosted exclusively in
CCE.Worker.APIs publish events only and do not execute consumer workloads.
Consumer | Event(s) | Purpose | Concurrency -- | -- | -- | -- FeedConsumer | PostCreated | Populate Redis feeds and timelines | 20 VoteConsumer | VoteCreated | Update Redis vote counters | 50 RankingConsumer | PostCreated | Rebuild community leaderboards | 1 NotificationConsumer | PostCreated, ReplyCreated, CommunityJoinRequested | Generate persisted notifications | 10 SignalRConsumer | PostCreated | Publish real-time community/topic updates | 30 NotificationMessageConsumer | NotificationMessage | Dispatch notification channels | 10SignalR Realtime Infrastructure
NotificationsHub
Supported groups:
Supported events:
ReceiveNotification
NewReply
VoteChanged
PollResultsChanged
NewPost
PostModerated
ContentModerated
PresenceChanged
TypingChanged
Scale-Out Support
Redis SignalR Backplane
Cross-instance group messaging
Distributed real-time notifications
Presence Tracking
RedisRealtimePresenceTrackerFeatures:
Per-post active viewer tracking
Connection lifecycle management
Graceful degradation when Redis is unavailable
Publisher Wrapper
CommunityRealtimePublisherAll Redis and SignalR operations are wrapped in exception handling to prevent user-facing failures.
Redis Infrastructure
Services
RedisFeedStore
Provides:
Feed storage
Sorted-set timelines
Community leaderboards
Feed metadata
RedisRealtimePresenceTracker
Provides:
User presence tracking
Active connection tracking
Redis-backed presence storage
Configuration
Resilience
All
RedisExceptioninstances are caught and logged as warnings.Redis outages will not result in HTTP 500 responses.
Domain Events Supported
Current domain events include:
Community
PostCreatedEvent
PostVotedEvent
ReplyCreatedEvent
CommunityJoinRequestedEvent
CommentCountChangedEvent
Content
NewsPublishedEvent
ResourcePublishedEvent
EventScheduledEvent
Country Content Requests
CountryContentRequestApprovedEvent
CountryContentRequestRejectedEvent
Expert Registration
ExpertRegistrationApprovedEvent
ExpertRegistrationRejectedEvent
Notification Pipeline
NotificationGateway
Flow:
Asynchronous Notification Dispatch
Introduced:
and
This replaces the previous in-process dispatcher and enables reliable asynchronous notification delivery.
Configuration
Development
Production
Set:
to enable broker-based messaging.
DevOps
Docker Services
Added support for:
Redis (
redis:7-alpine)RabbitMQ (
rabbitmq:3-management-alpine)via
docker-compose.yml.Health Checks
Added:
Features:
Host/port connectivity validation
3-second timeout
Optional transport fallback support
Benefits
Reliable event delivery through transactional outbox
Decoupled event-driven architecture
Production-ready RabbitMQ integration
Infrastructure-free local development using InMemory transport
Distributed real-time notifications with SignalR
Redis-backed feeds, leaderboards, and presence tracking
Graceful degradation when Redis is unavailable
Cross-process scalability via Redis SignalR backplane
Improved fault tolerance and observability