Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9d658e9

Browse files
committed
[Messenger] Allow to scope handlers per bus
1 parent 20cc065 commit 9d658e9

File tree

12 files changed

+478
-71
lines changed

12 files changed

+478
-71
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1483,7 +1483,7 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder
14831483
}
14841484

14851485
$container->setParameter($busId.'.middleware', $middleware);
1486-
$container->setDefinition($busId, (new Definition(MessageBus::class, array(array())))->addTag('messenger.bus'));
1486+
$container->register($busId, MessageBus::class)->addArgument(array())->addTag('messenger.bus');
14871487

14881488
if ($busId === $config['default_bus']) {
14891489
$container->setAlias('message_bus', $busId);

src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@
77
<services>
88
<defaults public="false" />
99

10-
<!-- Handlers -->
11-
<service id="messenger.handler_resolver" class="Symfony\Component\Messenger\Handler\Locator\ContainerHandlerLocator">
12-
<argument type="service" id="service_container"/>
13-
</service>
14-
1510
<!-- Asynchronous -->
1611
<service id="messenger.asynchronous.routing.sender_locator" class="Symfony\Component\Messenger\Asynchronous\Routing\SenderLocator">
1712
<argument type="service" id="messenger.sender_locator" />
@@ -32,7 +27,7 @@
3227
<!-- Middleware -->
3328
<service id="messenger.middleware.allow_no_handler" class="Symfony\Component\Messenger\Middleware\AllowNoHandlerMiddleware" abstract="true" />
3429
<service id="messenger.middleware.call_message_handler" class="Symfony\Component\Messenger\Middleware\HandleMessageMiddleware" abstract="true">
35-
<argument type="service" id="messenger.handler_resolver" />
30+
<argument /> <!-- Bus handler resolver -->
3631
</service>
3732

3833
<service id="messenger.middleware.validation" class="Symfony\Component\Messenger\Middleware\ValidationMiddleware" abstract="true">

src/Symfony/Component/Messenger/Command/DebugCommand.php

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Component\Messenger\Command;
1313

1414
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Exception\RuntimeException;
16+
use Symfony\Component\Console\Input\InputArgument;
1517
use Symfony\Component\Console\Input\InputInterface;
1618
use Symfony\Component\Console\Output\OutputInterface;
1719
use Symfony\Component\Console\Style\SymfonyStyle;
@@ -31,9 +33,9 @@ class DebugCommand extends Command
3133

3234
public function __construct(array $mapping)
3335
{
34-
parent::__construct();
35-
3636
$this->mapping = $mapping;
37+
38+
parent::__construct();
3739
}
3840

3941
/**
@@ -42,13 +44,18 @@ public function __construct(array $mapping)
4244
protected function configure()
4345
{
4446
$this
45-
->setDescription('Lists messages you can dispatch using the message bus')
47+
->addArgument('bus', InputArgument::OPTIONAL, sprintf('The bus id (one of %s)', implode(', ', array_keys($this->mapping))), null)
48+
->setDescription('Lists messages you can dispatch using the message buses')
4649
->setHelp(<<<'EOF'
4750
The <info>%command.name%</info> command displays all messages that can be
48-
dispatched using the message bus:
51+
dispatched using the message buses:
4952
5053
<info>php %command.full_name%</info>
5154
55+
Or for a specific bus only:
56+
57+
<info>php %command.full_name% command_bus</info>
58+
5259
EOF
5360
)
5461
;
@@ -61,21 +68,33 @@ protected function execute(InputInterface $input, OutputInterface $output)
6168
{
6269
$io = new SymfonyStyle($input, $output);
6370
$io->title('Messenger');
64-
$io->text('The following messages can be dispatched:');
65-
$io->newLine();
66-
67-
$tableRows = array();
68-
foreach ($this->mapping as $message => $handlers) {
69-
$tableRows[] = array(sprintf('<fg=cyan>%s</fg=cyan>', $message));
70-
foreach ($handlers as $handler) {
71-
$tableRows[] = array(sprintf(' handled by %s', $handler));
71+
72+
$mapping = $this->mapping;
73+
if ($bus = $input->getArgument('bus')) {
74+
if (!isset($mapping[$bus])) {
75+
throw new RuntimeException(sprintf('Bus "%s" does not exist. Known buses are %s.', $bus, implode(', ', array_keys($this->mapping))));
7276
}
77+
$mapping = array($bus => $mapping[$bus]);
7378
}
7479

75-
if ($tableRows) {
76-
$io->table(array(), $tableRows);
77-
} else {
78-
$io->text('No messages were found that have valid handlers.');
80+
foreach ($mapping as $bus => $handlersByMessage) {
81+
$io->section($bus);
82+
83+
$tableRows = array();
84+
foreach ($handlersByMessage as $message => $handlers) {
85+
$tableRows[] = array(sprintf('<fg=cyan>%s</fg=cyan>', $message));
86+
foreach ($handlers as $handler) {
87+
$tableRows[] = array(sprintf(' handled by <info>%s</>', $handler));
88+
}
89+
}
90+
91+
if ($tableRows) {
92+
$io->text('The following messages can be dispatched:');
93+
$io->newLine();
94+
$io->table(array(), $tableRows);
95+
} else {
96+
$io->warning(sprintf('No handled message found in bus "%s".', $bus));
97+
}
7998
}
8099
}
81100
}

src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
2121
use Symfony\Component\DependencyInjection\Reference;
2222
use Symfony\Component\Messenger\Handler\ChainHandler;
23+
use Symfony\Component\Messenger\Handler\Locator\ContainerHandlerLocator;
2324
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
2425
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
2526
use Symfony\Component\Messenger\TraceableMessageBus;
@@ -51,11 +52,13 @@ public function __construct(string $handlerTag = 'messenger.message_handler', st
5152
*/
5253
public function process(ContainerBuilder $container)
5354
{
54-
if (!$container->hasDefinition('messenger.handler_resolver')) {
55+
if (!$container->has('message_bus')) {
5556
return;
5657
}
5758

59+
$busIds = array();
5860
foreach ($container->findTaggedServiceIds($this->busTag) as $busId => $tags) {
61+
$busIds[] = $busId;
5962
if ($container->hasParameter($busMiddlewareParameter = $busId.'.middleware')) {
6063
$this->registerBusMiddleware($container, $busId, $container->getParameter($busMiddlewareParameter));
6164

@@ -69,16 +72,20 @@ public function process(ContainerBuilder $container)
6972

7073
$this->registerReceivers($container);
7174
$this->registerSenders($container);
72-
$this->registerHandlers($container);
75+
$this->registerHandlers($container, $busIds);
7376
}
7477

75-
private function registerHandlers(ContainerBuilder $container)
78+
private function registerHandlers(ContainerBuilder $container, array $busIds)
7679
{
7780
$definitions = array();
78-
$handlersByMessage = array();
81+
$handlersByBusAndMessage = array();
7982

8083
foreach ($container->findTaggedServiceIds($this->handlerTag, true) as $serviceId => $tags) {
8184
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+
8289
$r = $container->getReflectionClass($container->getDefinition($serviceId)->getClass());
8390

8491
if (isset($tag['handles'])) {
@@ -88,6 +95,7 @@ private function registerHandlers(ContainerBuilder $container)
8895
}
8996

9097
$priority = $tag['priority'] ?? 0;
98+
$handlerBuses = (array) ($tag['bus'] ?? $busIds);
9199

92100
foreach ($handles as $messageClass => $method) {
93101
if (\is_int($messageClass)) {
@@ -123,38 +131,57 @@ private function registerHandlers(ContainerBuilder $container)
123131
$definitions[$serviceId = '.messenger.method_on_object_wrapper.'.ContainerBuilder::hash($messageClass.':'.$messagePriority.':'.$serviceId.':'.$method)] = $wrapperDefinition;
124132
}
125133

126-
$handlersByMessage[$messageClass][$messagePriority][] = new Reference($serviceId);
134+
foreach ($handlerBuses as $handlerBus) {
135+
$handlersByBusAndMessage[$handlerBus][$messageClass][$messagePriority][] = $serviceId;
136+
}
127137
}
128138
}
129139
}
130140

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+
}
134146
}
135147

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+
}
146162
}
147163
}
148164
$container->addDefinitions($definitions);
149165

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+
}
152176

153177
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);
158185
}
159186
}
160187

0 commit comments

Comments
 (0)