20
20
use Symfony \Component \DependencyInjection \Exception \RuntimeException ;
21
21
use Symfony \Component \DependencyInjection \Reference ;
22
22
use Symfony \Component \Messenger \Handler \ChainHandler ;
23
+ use Symfony \Component \Messenger \Handler \Locator \ContainerHandlerLocator ;
23
24
use Symfony \Component \Messenger \Handler \MessageHandlerInterface ;
24
25
use Symfony \Component \Messenger \Handler \MessageSubscriberInterface ;
25
26
use Symfony \Component \Messenger \TraceableMessageBus ;
@@ -51,11 +52,13 @@ public function __construct(string $handlerTag = 'messenger.message_handler', st
51
52
*/
52
53
public function process (ContainerBuilder $ container )
53
54
{
54
- if (!$ container ->hasDefinition ( ' messenger.handler_resolver ' )) {
55
+ if (!$ container ->has ( ' message_bus ' )) {
55
56
return ;
56
57
}
57
58
59
+ $ busIds = array ();
58
60
foreach ($ container ->findTaggedServiceIds ($ this ->busTag ) as $ busId => $ tags ) {
61
+ $ busIds [] = $ busId ;
59
62
if ($ container ->hasParameter ($ busMiddlewareParameter = $ busId .'.middleware ' )) {
60
63
$ this ->registerBusMiddleware ($ container , $ busId , $ container ->getParameter ($ busMiddlewareParameter ));
61
64
@@ -69,16 +72,20 @@ public function process(ContainerBuilder $container)
69
72
70
73
$ this ->registerReceivers ($ container );
71
74
$ this ->registerSenders ($ container );
72
- $ this ->registerHandlers ($ container );
75
+ $ this ->registerHandlers ($ container, $ busIds );
73
76
}
74
77
75
- private function registerHandlers (ContainerBuilder $ container )
78
+ private function registerHandlers (ContainerBuilder $ container, array $ busIds )
76
79
{
77
80
$ definitions = array ();
78
- $ handlersByMessage = array ();
81
+ $ handlersByBusAndMessage = array ();
79
82
80
83
foreach ($ container ->findTaggedServiceIds ($ this ->handlerTag , true ) as $ serviceId => $ tags ) {
81
84
foreach ($ tags as $ tag ) {
85
+ if (isset ($ tag ['bus ' ]) && !\in_array ($ tag ['bus ' ], $ busIds , true )) {
86
+ throw new RuntimeException (sprintf ('Invalid handler service "%s": bus "%s" specified on the tag "%s" does not exist (known ones are: %s). ' , $ serviceId , $ tag ['bus ' ], $ this ->handlerTag , implode (', ' , $ busIds )));
87
+ }
88
+
82
89
$ r = $ container ->getReflectionClass ($ container ->getDefinition ($ serviceId )->getClass ());
83
90
84
91
if (isset ($ tag ['handles ' ])) {
@@ -88,6 +95,7 @@ private function registerHandlers(ContainerBuilder $container)
88
95
}
89
96
90
97
$ priority = $ tag ['priority ' ] ?? 0 ;
98
+ $ handlerBuses = (array ) ($ tag ['bus ' ] ?? $ busIds );
91
99
92
100
foreach ($ handles as $ messageClass => $ method ) {
93
101
if (\is_int ($ messageClass )) {
@@ -123,38 +131,57 @@ private function registerHandlers(ContainerBuilder $container)
123
131
$ definitions [$ serviceId = '.messenger.method_on_object_wrapper. ' .ContainerBuilder::hash ($ messageClass .': ' .$ messagePriority .': ' .$ serviceId .': ' .$ method )] = $ wrapperDefinition ;
124
132
}
125
133
126
- $ handlersByMessage [$ messageClass ][$ messagePriority ][] = new Reference ($ serviceId );
134
+ foreach ($ handlerBuses as $ handlerBus ) {
135
+ $ handlersByBusAndMessage [$ handlerBus ][$ messageClass ][$ messagePriority ][] = $ serviceId ;
136
+ }
127
137
}
128
138
}
129
139
}
130
140
131
- foreach ($ handlersByMessage as $ message => $ handlers ) {
132
- krsort ($ handlersByMessage [$ message ]);
133
- $ handlersByMessage [$ message ] = array_merge (...$ handlersByMessage [$ message ]);
141
+ foreach ($ handlersByBusAndMessage as $ bus => $ handlersByMessage ) {
142
+ foreach ($ handlersByMessage as $ message => $ handlersByPriority ) {
143
+ krsort ($ handlersByPriority );
144
+ $ handlersByBusAndMessage [$ bus ][$ message ] = array_unique (array_merge (...$ handlersByPriority ));
145
+ }
134
146
}
135
147
136
- $ handlersLocatorMapping = array ();
137
- foreach ($ handlersByMessage as $ message => $ handlers ) {
138
- if (1 === \count ($ handlers )) {
139
- $ handlersLocatorMapping ['handler. ' .$ message ] = current ($ handlers );
140
- } else {
141
- $ d = new Definition (ChainHandler::class, array ($ handlers ));
142
- $ d ->setPrivate (true );
143
- $ serviceId = hash ('sha1 ' , $ message );
144
- $ definitions [$ serviceId ] = $ d ;
145
- $ handlersLocatorMapping ['handler. ' .$ message ] = new Reference ($ serviceId );
148
+ $ handlersLocatorMappingByBus = array ();
149
+ foreach ($ handlersByBusAndMessage as $ bus => $ handlersByMessage ) {
150
+ foreach ($ handlersByMessage as $ message => $ handlersIds ) {
151
+ if (1 === \count ($ handlersIds )) {
152
+ $ handlersLocatorMappingByBus [$ bus ]['handler. ' .$ message ] = new Reference (current ($ handlersIds ));
153
+ } else {
154
+ $ chainHandler = new Definition (ChainHandler::class, array (array_map (function (string $ handlerId ): Reference {
155
+ return new Reference ($ handlerId );
156
+ }, $ handlersIds )));
157
+ $ chainHandler ->setPrivate (true );
158
+ $ serviceId = '.messenger.chain_handler. ' .ContainerBuilder::hash ($ bus .$ message );
159
+ $ definitions [$ serviceId ] = $ chainHandler ;
160
+ $ handlersLocatorMappingByBus [$ bus ]['handler. ' .$ message ] = new Reference ($ serviceId );
161
+ }
146
162
}
147
163
}
148
164
$ container ->addDefinitions ($ definitions );
149
165
150
- $ handlerResolver = $ container ->getDefinition ('messenger.handler_resolver ' );
151
- $ handlerResolver ->replaceArgument (0 , ServiceLocatorTagPass::register ($ container , $ handlersLocatorMapping ));
166
+ foreach ($ busIds as $ bus ) {
167
+ $ container ->register ($ resolverName = "$ bus.messenger.handler_resolver " , ContainerHandlerLocator::class)
168
+ ->setArgument (0 , ServiceLocatorTagPass::register ($ container , $ handlersLocatorMappingByBus [$ bus ] ?? array ()))
169
+ ;
170
+ if ($ container ->has ($ callMessageHandlerId = "$ bus.middleware.call_message_handler " )) {
171
+ $ container ->getDefinition ($ callMessageHandlerId )
172
+ ->replaceArgument (0 , new Reference ($ resolverName ))
173
+ ;
174
+ }
175
+ }
152
176
153
177
if ($ container ->hasDefinition ('console.command.messenger_debug ' )) {
154
- $ container ->getDefinition ('console.command.messenger_debug ' )
155
- ->replaceArgument (0 , array_map (function (array $ handlers ): array {
156
- return array_map ('strval ' , $ handlers );
157
- }, $ handlersByMessage ));
178
+ $ debugCommandMapping = $ handlersByBusAndMessage ;
179
+ foreach ($ busIds as $ bus ) {
180
+ if (!isset ($ debugCommandMapping [$ bus ])) {
181
+ $ debugCommandMapping [$ bus ] = array ();
182
+ }
183
+ }
184
+ $ container ->getDefinition ('console.command.messenger_debug ' )->replaceArgument (0 , $ debugCommandMapping );
158
185
}
159
186
}
160
187
0 commit comments