44using System . Text ;
55using System . Threading . Tasks ;
66using Microsoft . Extensions . Logging ;
7+ using RabbitMQ . Client . Core . DependencyInjection . Extensions ;
78using RabbitMQ . Client . Events ;
89
910namespace RabbitMQ . Client . Core . DependencyInjection
@@ -20,6 +21,7 @@ public class MessageHandlingService : IMessageHandlingService
2021 readonly IDictionary < string , IList < IAsyncMessageHandler > > _asyncMessageHandlers ;
2122 readonly IDictionary < string , IList < INonCyclicMessageHandler > > _nonCyclicHandlers ;
2223 readonly IDictionary < string , IList < IAsyncNonCyclicMessageHandler > > _asyncNonCyclicHandlers ;
24+ readonly IEnumerable < TreeNode > _routeTree ;
2325 readonly ILogger < MessageHandlingService > _logger ;
2426
2527 public MessageHandlingService (
@@ -32,11 +34,12 @@ public MessageHandlingService(
3234 ILogger < MessageHandlingService > logger )
3335 {
3436 _exchanges = exchanges ;
35- var messageHandlerRouters = TransformMessageHandlerRouters ( routers ) ;
36- _messageHandlers = TransformMessageHandlersCollection ( messageHandlers , messageHandlerRouters ) ;
37- _asyncMessageHandlers = TransformMessageHandlersCollection ( asyncMessageHandlers , messageHandlerRouters ) ;
38- _nonCyclicHandlers = TransformMessageHandlersCollection ( nonCyclicHandlers , messageHandlerRouters ) ;
39- _asyncNonCyclicHandlers = TransformMessageHandlersCollection ( asyncNonCyclicHandlers , messageHandlerRouters ) ;
37+ var routersDictionary = TransformMessageHandlerRoutersToDictionary ( routers ) ;
38+ _messageHandlers = TransformMessageHandlersCollectionToDictionary ( messageHandlers , routersDictionary ) ;
39+ _asyncMessageHandlers = TransformMessageHandlersCollectionToDictionary ( asyncMessageHandlers , routersDictionary ) ;
40+ _nonCyclicHandlers = TransformMessageHandlersCollectionToDictionary ( nonCyclicHandlers , routersDictionary ) ;
41+ _asyncNonCyclicHandlers = TransformMessageHandlersCollectionToDictionary ( asyncNonCyclicHandlers , routersDictionary ) ;
42+ _routeTree = ConstructRoutesTree ( routers ) ;
4043 _logger = logger ;
4144 }
4245
@@ -54,38 +57,8 @@ public void HandleMessageReceivingEvent(BasicDeliverEventArgs eventArgs, IQueueS
5457
5558 try
5659 {
57- if ( _asyncMessageHandlers . ContainsKey ( eventArgs . RoutingKey ) )
58- {
59- var tasks = new List < Task > ( ) ;
60- foreach ( var handler in _asyncMessageHandlers [ eventArgs . RoutingKey ] )
61- {
62- tasks . Add ( RunAsyncMessageHandler ( handler , message , eventArgs . RoutingKey ) ) ;
63- }
64- Task . WaitAll ( tasks . ToArray ( ) ) ;
65- }
66- if ( _messageHandlers . ContainsKey ( eventArgs . RoutingKey ) )
67- {
68- foreach ( var handler in _messageHandlers [ eventArgs . RoutingKey ] )
69- {
70- RunMessageHandler ( handler , message , eventArgs . RoutingKey ) ;
71- }
72- }
73- if ( _asyncNonCyclicHandlers . ContainsKey ( eventArgs . RoutingKey ) )
74- {
75- var tasks = new List < Task > ( ) ;
76- foreach ( var handler in _asyncNonCyclicHandlers [ eventArgs . RoutingKey ] )
77- {
78- tasks . Add ( RunAsyncNonCyclicMessageHandler ( handler , message , eventArgs . RoutingKey , queueService ) ) ;
79- }
80- Task . WaitAll ( tasks . ToArray ( ) ) ;
81- }
82- if ( _nonCyclicHandlers . ContainsKey ( eventArgs . RoutingKey ) )
83- {
84- foreach ( var handler in _nonCyclicHandlers [ eventArgs . RoutingKey ] )
85- {
86- RunNonCyclicMessageHandler ( handler , message , eventArgs . RoutingKey , queueService ) ;
87- }
88- }
60+ var matchingRoutes = GetMatchingRoutePatterns ( eventArgs . RoutingKey ) ;
61+ ProcessMessage ( message , queueService , matchingRoutes ) ;
8962 queueService . Channel . BasicAck ( eventArgs . DeliveryTag , false ) ;
9063 _logger . LogInformation ( $ "Message processing finished successfully. Acknowledge has been sent with deliveryTag { eventArgs . DeliveryTag } .") ;
9164 }
@@ -122,6 +95,80 @@ public void HandleMessageReceivingEvent(BasicDeliverEventArgs eventArgs, IQueueS
12295 }
12396 }
12497
98+ IEnumerable < string > GetMatchingRoutePatterns ( string routingKey )
99+ {
100+ var routingKeyParts = routingKey . Split ( "." ) ;
101+ return WildcardExtensions . GetMatchingRoutePatterns ( _routeTree , routingKeyParts ) . ToList ( ) ;
102+ }
103+
104+ void ProcessMessage ( string message , IQueueService queueService , IEnumerable < string > matchingRoutes )
105+ {
106+ var executedHandlers = new List < Type > ( ) ;
107+ foreach ( var matchingRoute in matchingRoutes )
108+ {
109+ if ( _asyncMessageHandlers . ContainsKey ( matchingRoute ) )
110+ {
111+ var tasks = new List < Task > ( ) ;
112+ foreach ( var handler in _asyncMessageHandlers [ matchingRoute ] )
113+ {
114+ var handlerType = handler . GetType ( ) ;
115+ if ( executedHandlers . Contains ( handlerType ) )
116+ {
117+ continue ;
118+ }
119+
120+ executedHandlers . Add ( handlerType ) ;
121+ tasks . Add ( RunAsyncMessageHandler ( handler , message , matchingRoute ) ) ;
122+ }
123+ Task . WaitAll ( tasks . ToArray ( ) ) ;
124+ }
125+ if ( _messageHandlers . ContainsKey ( matchingRoute ) )
126+ {
127+ foreach ( var handler in _messageHandlers [ matchingRoute ] )
128+ {
129+ var handlerType = handler . GetType ( ) ;
130+ if ( executedHandlers . Contains ( handlerType ) )
131+ {
132+ continue ;
133+ }
134+
135+ executedHandlers . Add ( handlerType ) ;
136+ RunMessageHandler ( handler , message , matchingRoute ) ;
137+ }
138+ }
139+ if ( _asyncNonCyclicHandlers . ContainsKey ( matchingRoute ) )
140+ {
141+ var tasks = new List < Task > ( ) ;
142+ foreach ( var handler in _asyncNonCyclicHandlers [ matchingRoute ] )
143+ {
144+ var handlerType = handler . GetType ( ) ;
145+ if ( executedHandlers . Contains ( handlerType ) )
146+ {
147+ continue ;
148+ }
149+
150+ executedHandlers . Add ( handlerType ) ;
151+ tasks . Add ( RunAsyncNonCyclicMessageHandler ( handler , message , matchingRoute , queueService ) ) ;
152+ }
153+ Task . WaitAll ( tasks . ToArray ( ) ) ;
154+ }
155+ if ( _nonCyclicHandlers . ContainsKey ( matchingRoute ) )
156+ {
157+ foreach ( var handler in _nonCyclicHandlers [ matchingRoute ] )
158+ {
159+ var handlerType = handler . GetType ( ) ;
160+ if ( executedHandlers . Contains ( handlerType ) )
161+ {
162+ continue ;
163+ }
164+
165+ executedHandlers . Add ( handlerType ) ;
166+ RunNonCyclicMessageHandler ( handler , message , matchingRoute , queueService ) ;
167+ }
168+ }
169+ }
170+ }
171+
125172 void RunMessageHandler ( IMessageHandler handler , string message , string routingKey )
126173 {
127174 ValidateHandler ( handler ) ;
@@ -162,30 +209,38 @@ void ValidateHandler<T>(T messageHandler)
162209 }
163210 }
164211
165- static IDictionary < Type , List < string > > TransformMessageHandlerRouters ( IEnumerable < MessageHandlerRouter > routers )
212+ static IEnumerable < TreeNode > ConstructRoutesTree ( IEnumerable < MessageHandlerRouter > routers )
213+ {
214+ var routePatterns = routers . SelectMany ( x => x . RoutePatterns ) . Distinct ( ) ;
215+ return WildcardExtensions . ConstructRoutesTree ( routePatterns ) ;
216+ }
217+
218+ static IDictionary < Type , List < string > > TransformMessageHandlerRoutersToDictionary ( IEnumerable < MessageHandlerRouter > routers )
166219 {
167220 var dictionary = new Dictionary < Type , List < string > > ( ) ;
168221 foreach ( var router in routers )
169222 {
170223 if ( dictionary . ContainsKey ( router . Type ) )
171224 {
172- dictionary [ router . Type ] = dictionary [ router . Type ] . Union ( router . RoutingKeys ) . ToList ( ) ;
225+ dictionary [ router . Type ] = dictionary [ router . Type ] . Union ( router . RoutePatterns ) . ToList ( ) ;
173226 }
174227 else
175228 {
176- dictionary . Add ( router . Type , router . RoutingKeys ) ;
229+ dictionary . Add ( router . Type , router . RoutePatterns ) ;
177230 }
178231 }
179232 return dictionary ;
180233 }
181234
182- static IDictionary < string , IList < T > > TransformMessageHandlersCollection < T > ( IEnumerable < T > messageHandlers , IDictionary < Type , List < string > > messageHandlerRouters )
235+ static IDictionary < string , IList < T > > TransformMessageHandlersCollectionToDictionary < T > (
236+ IEnumerable < T > messageHandlers ,
237+ IDictionary < Type , List < string > > routersDictionary )
183238 {
184239 var dictionary = new Dictionary < string , IList < T > > ( ) ;
185240 foreach ( var handler in messageHandlers )
186241 {
187242 var type = handler . GetType ( ) ;
188- foreach ( var routingKey in messageHandlerRouters [ type ] )
243+ foreach ( var routingKey in routersDictionary [ type ] )
189244 {
190245 if ( dictionary . ContainsKey ( routingKey ) )
191246 {
0 commit comments