Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcc6f13d

Browse files
committed
Allows to register handlers on a specific transport (and get rid of this handler alias)
1 parent7e56ef1 commitcc6f13d

23 files changed

+423
-209
lines changed

‎src/Symfony/Component/Messenger/CHANGELOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ CHANGELOG
8080
* Added a Doctrine transport. For example, use the`doctrine://default` DSN (this uses the`default` Doctrine entity manager)
8181
*[BC BREAK] The`getConnectionConfiguration` method on Amqp's`Connection` has been removed.
8282
*[BC BREAK] A`HandlerFailedException` exception will be thrown if one or more handler fails.
83+
*[BC BREAK] The`HandlersLocationInterface::getHandlers` method needs to return`HandlerDescriptor`
84+
instances instead of callables.
85+
*[BC BREAK] The`handlerAlias` has been renamed to`handlerName` on the`HandledStamp`.
86+
*[BC BREAK] The`ReceivedStamp` needs to exposes the name of the transport from which the message
87+
has been received.
8388

8489
4.2.0
8590
-----

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ protected function execute(InputInterface $input, OutputInterface $output)
8484
foreach ($handlersByMessageas$message =>$handlers) {
8585
$tableRows[] = [sprintf('<fg=cyan>%s</fg=cyan>',$message)];
8686
foreach ($handlersas$handler) {
87-
$tableRows[] = [sprintf(' handled by <info>%s</>',$handler)];
87+
$tableRows[] = [
88+
sprintf(' handled by <info>%s</>',$handler[0]).$this->formatConditions($handler[1]),
89+
];
8890
}
8991
}
9092

@@ -97,4 +99,18 @@ protected function execute(InputInterface $input, OutputInterface $output)
9799
}
98100
}
99101
}
102+
103+
privatefunctionformatConditions(array$options):string
104+
{
105+
if (!$options) {
106+
return'';
107+
}
108+
109+
$optionsMapping = [];
110+
foreach ($optionsas$key =>$value) {
111+
$optionsMapping[] =''.$key.'='.$value;
112+
}
113+
114+
return' (when'.implode(',',$optionsMapping).')';
115+
}
100116
}

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

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
useSymfony\Component\DependencyInjection\Definition;
2020
useSymfony\Component\DependencyInjection\Exception\RuntimeException;
2121
useSymfony\Component\DependencyInjection\Reference;
22+
useSymfony\Component\Messenger\Handler\HandlerDescriptor;
2223
useSymfony\Component\Messenger\Handler\HandlersLocator;
2324
useSymfony\Component\Messenger\Handler\MessageSubscriberInterface;
2425
useSymfony\Component\Messenger\TraceableMessageBus;
@@ -94,32 +95,33 @@ private function registerHandlers(ContainerBuilder $container, array $busIds)
9495
$message =null;
9596
$handlerBuses = (array) ($tag['bus'] ??$busIds);
9697

97-
foreach ($handlesas$message =>$method) {
98+
foreach ($handlesas$message =>$options) {
9899
$buses =$handlerBuses;
100+
99101
if (\is_int($message)) {
100-
$message =$method;
101-
$method ='__invoke';
102+
if (\is_string($options)) {
103+
$message =$options;
104+
$options = [];
105+
}else {
106+
thrownewRuntimeException(sprintf('The handler configuration needs to return an array of messages or an associated array of message and configuration. Found value of type "%s" at position "%d" for service "%s".',\gettype($options),$message,$serviceId));
107+
}
102108
}
103109

104-
if (\is_array($message)) {
105-
list($message,$priority) =$message;
106-
}else {
107-
$priority =$tag['priority'] ??0;
110+
if (\is_string($options)) {
111+
$options = ['method' =>$options];
108112
}
109113

110-
if (\is_array($method)) {
111-
if (isset($method['bus'])) {
112-
if (!\in_array($method['bus'],$busIds)) {
113-
$messageLocation =isset($tag['handles']) ?'declared in your tag attribute "handles"' :$r->implementsInterface(MessageSubscriberInterface::class) ?sprintf('returned by method "%s::getHandledMessages()"',$r->getName()) :sprintf('used as argument type in method "%s::%s()"',$r->getName(),$method);
114+
$priority =$tag['priority'] ??$options['priority'] ??0;
115+
$method =$options['method'] ??'__invoke';
114116

115-
thrownewRuntimeException(sprintf('Invalid configuration %s for message "%s": bus "%s" does not exist.',$messageLocation,$message,$method['bus']));
116-
}
117+
if (isset($options['bus'])) {
118+
if (!\in_array($options['bus'],$busIds)) {
119+
$messageLocation =isset($tag['handles']) ?'declared in your tag attribute "handles"' :$r->implementsInterface(MessageSubscriberInterface::class) ?sprintf('returned by method "%s::getHandledMessages()"',$r->getName()) :sprintf('used as argument type in method "%s::%s()"',$r->getName(),$method);
117120

118-
$buses = [$method['bus']];
121+
thrownewRuntimeException(sprintf('Invalid configuration %s for message "%s": bus "%s" does not exist.',$messageLocation,$message,$options['bus']));
119122
}
120123

121-
$priority =$method['priority'] ??$priority;
122-
$method =$method['method'] ??'__invoke';
124+
$buses = [$options['bus']];
123125
}
124126

125127
if ('*' !==$message && !class_exists($message) && !interface_exists($message,false)) {
@@ -141,7 +143,7 @@ private function registerHandlers(ContainerBuilder $container, array $busIds)
141143
}
142144

143145
foreach ($busesas$handlerBus) {
144-
$handlersByBusAndMessage[$handlerBus][$message][$priority][] =$definitionId;
146+
$handlersByBusAndMessage[$handlerBus][$message][$priority][] =[$definitionId,$options];
145147
}
146148
}
147149

@@ -154,15 +156,20 @@ private function registerHandlers(ContainerBuilder $container, array $busIds)
154156
foreach ($handlersByBusAndMessageas$bus =>$handlersByMessage) {
155157
foreach ($handlersByMessageas$message =>$handlersByPriority) {
156158
krsort($handlersByPriority);
157-
$handlersByBusAndMessage[$bus][$message] =array_unique(array_merge(...$handlersByPriority));
159+
$handlersByBusAndMessage[$bus][$message] =array_merge(...$handlersByPriority);
158160
}
159161
}
160162

161163
$handlersLocatorMappingByBus = [];
162164
foreach ($handlersByBusAndMessageas$bus =>$handlersByMessage) {
163-
foreach ($handlersByMessageas$message =>$handlerIds) {
164-
$handlers =array_map(function (string$handlerId) {returnnewReference($handlerId); },$handlerIds);
165-
$handlersLocatorMappingByBus[$bus][$message] =newIteratorArgument($handlers);
165+
foreach ($handlersByMessageas$message =>$handlers) {
166+
$handlerDescriptors = [];
167+
foreach ($handlersas$handler) {
168+
$definitions[$definitionId ='.messenger.handler_descriptor.'.ContainerBuilder::hash($bus.':'.$message.':'.$handler[0])] = (newDefinition(HandlerDescriptor::class))->setArguments([newReference($handler[0]),$handler[1]]);
169+
$handlerDescriptors[] =newReference($definitionId);
170+
}
171+
172+
$handlersLocatorMappingByBus[$bus][$message] =newIteratorArgument($handlerDescriptors);
166173
}
167174
}
168175
$container->addDefinitions($definitions);

‎src/Symfony/Component/Messenger/HandleTrait.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ private function handle($message)
5252

5353
if (\count($handledStamps) >1) {
5454
$handlers =implode(',',array_map(function (HandledStamp$stamp):string {
55-
returnsprintf('"%s"',$stamp->getHandlerAlias() ??$stamp->getCallableName());
55+
returnsprintf('"%s"',$stamp->getHandlerName());
5656
},$handledStamps));
5757

5858
thrownewLogicException(sprintf('Message of type "%s" was handled multiple times. Only one handler is expected when using "%s::%s()", got %d: %s.',\get_class($envelope->getMessage()),\get_class($this),__FUNCTION__,\count($handledStamps),$handlers));
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Messenger\Handler;
13+
14+
/**
15+
* Describe a handler and the possible associated options, such as `transport`, `bus`, etc.
16+
*
17+
* @author Samuel Roze <samuel.roze@gmail.com>
18+
*/
19+
finalclass HandlerDescriptor
20+
{
21+
private$handler;
22+
private$options;
23+
24+
publicfunction__construct(callable$handler,array$options = [])
25+
{
26+
$this->handler =$handler;
27+
$this->options =$options;
28+
}
29+
30+
publicfunctiongetHandler():callable
31+
{
32+
return$this->handler;
33+
}
34+
35+
publicfunctiongetName():string
36+
{
37+
$name =$this->callableName($this->handler);
38+
$alias =$this->options['alias'] ??null;
39+
40+
if (null !==$alias) {
41+
$name .='@'.$alias;
42+
}
43+
44+
return$name;
45+
}
46+
47+
publicfunctiongetOption(string$option)
48+
{
49+
return$this->options[$option] ??null;
50+
}
51+
52+
privatefunctioncallableName(callable$handler)
53+
{
54+
if (\is_array($handler)) {
55+
if (\is_object($handler[0])) {
56+
return\get_class($handler[0]).'::'.$handler[1];
57+
}
58+
59+
return$handler[0].'::'.$handler[1];
60+
}
61+
62+
if (\is_string($handler)) {
63+
return$handler;
64+
}
65+
66+
if ($handlerinstanceof \Closure) {
67+
$r =new \ReflectionFunction($handler);
68+
if (false !==strpos($r->name,'{closure}')) {
69+
return'Closure';
70+
}
71+
if ($class =$r->getClosureScopeClass()) {
72+
return$class->name.'::'.$r->name;
73+
}
74+
75+
return$r->name;
76+
}
77+
78+
return\get_class($handler).'::__invoke';
79+
}
80+
}

‎src/Symfony/Component/Messenger/Handler/HandlersLocator.php‎

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
namespaceSymfony\Component\Messenger\Handler;
1313

1414
useSymfony\Component\Messenger\Envelope;
15+
useSymfony\Component\Messenger\Stamp\ReceivedStamp;
1516

1617
/**
1718
* Maps a message to a list of handlers.
1819
*
1920
* @author Nicolas Grekas <p@tchwork.com>
21+
* @author Samuel Roze <samuel.roze@gmail.com>
2022
*
2123
* @experimental in 4.2
2224
*/
@@ -25,7 +27,7 @@ class HandlersLocator implements HandlersLocatorInterface
2527
private$handlers;
2628

2729
/**
28-
* @param callable[][] $handlers
30+
* @paramHandlerDescriptor[][]|callable[][] $handlers
2931
*/
3032
publicfunction__construct(array$handlers)
3133
{
@@ -40,10 +42,23 @@ public function getHandlers(Envelope $envelope): iterable
4042
$seen = [];
4143

4244
foreach (self::listTypes($envelope)as$type) {
43-
foreach ($this->handlers[$type] ?? []as$alias =>$handler) {
44-
if (!\in_array($handler,$seen,true)) {
45-
yield$alias =>$seen[] =$handler;
45+
foreach ($this->handlers[$type] ?? []as$handlerDescriptor) {
46+
if (\is_callable($handlerDescriptor)) {
47+
$handlerDescriptor =newHandlerDescriptor($handlerDescriptor);
4648
}
49+
50+
if (!$this->shouldHandle($envelope,$handlerDescriptor)) {
51+
continue;
52+
}
53+
54+
$name =$handlerDescriptor->getName();
55+
if (\in_array($name,$seen)) {
56+
continue;
57+
}
58+
59+
$seen[] =$name;
60+
61+
yield$handlerDescriptor;
4762
}
4863
}
4964
}
@@ -60,4 +75,17 @@ public static function listTypes(Envelope $envelope): array
6075
+class_implements($class)
6176
+ ['*' =>'*'];
6277
}
78+
79+
privatefunctionshouldHandle(Envelope$envelope,HandlerDescriptor$handlerDescriptor)
80+
{
81+
if (null ===$received =$envelope->last(ReceivedStamp::class)) {
82+
returntrue;
83+
}
84+
85+
if (null ===$expectedTransport =$handlerDescriptor->getOption('transport')) {
86+
returntrue;
87+
}
88+
89+
return$received->getTransportName() ===$expectedTransport;
90+
}
6391
}

‎src/Symfony/Component/Messenger/Handler/HandlersLocatorInterface.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ interface HandlersLocatorInterface
2525
/**
2626
* Returns the handlers for the given message name.
2727
*
28-
* @return iterable|callable[] Indexed by handler alias if available
28+
* @return iterable|HandlerDescriptor[] Indexed by handler alias if available
2929
*/
3030
publicfunctiongetHandlers(Envelope$envelope):iterable;
3131
}

‎src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php‎

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
useSymfony\Component\Messenger\Envelope;
1717
useSymfony\Component\Messenger\Exception\HandlerFailedException;
1818
useSymfony\Component\Messenger\Exception\NoHandlerForMessageException;
19+
useSymfony\Component\Messenger\Handler\HandlerDescriptor;
1920
useSymfony\Component\Messenger\Handler\HandlersLocatorInterface;
2021
useSymfony\Component\Messenger\Stamp\HandledStamp;
2122

@@ -54,17 +55,16 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope
5455
];
5556

5657
$exceptions = [];
57-
foreach ($this->handlersLocator->getHandlers($envelope)as$alias =>$handler) {
58-
$alias =\is_string($alias) ?$alias :null;
59-
60-
if ($this->messageHasAlreadyBeenHandled($envelope,$handler,$alias)) {
58+
foreach ($this->handlersLocator->getHandlers($envelope)as$handlerDescriptor) {
59+
if ($this->messageHasAlreadyBeenHandled($envelope,$handlerDescriptor)) {
6160
continue;
6261
}
6362

6463
try {
65-
$handledStamp = HandledStamp::fromCallable($handler,$handler($message),$alias);
64+
$handler =$handlerDescriptor->getHandler();
65+
$handledStamp = HandledStamp::fromDescriptor($handlerDescriptor,$handler($message));
6666
$envelope =$envelope->with($handledStamp);
67-
$this->logger->info('Message "{class}" handled by "{handler}"',$context + ['handler' =>$handledStamp->getCallableName()]);
67+
$this->logger->info('Message "{class}" handled by "{handler}"',$context + ['handler' =>$handledStamp->getHandlerName()]);
6868
}catch (\Throwable$e) {
6969
$exceptions[] =$e;
7070
}
@@ -85,12 +85,11 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope
8585
return$stack->next()->handle($envelope,$stack);
8686
}
8787

88-
privatefunctionmessageHasAlreadyBeenHandled(Envelope$envelope,callable$handler, ?string$alias):bool
88+
privatefunctionmessageHasAlreadyBeenHandled(Envelope$envelope,HandlerDescriptor$handlerDescriptor):bool
8989
{
9090
$some =array_filter($envelope
91-
->all(HandledStamp::class),function (HandledStamp$stamp)use ($handler,$alias) {
92-
return$stamp->getCallableName() === HandledStamp::getNameFromCallable($handler) &&
93-
$stamp->getHandlerAlias() ===$alias;
91+
->all(HandledStamp::class),function (HandledStamp$stamp)use ($handlerDescriptor) {
92+
return$stamp->getHandlerName() ===$handlerDescriptor->getName();
9493
});
9594

9695
return\count($some) >0;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp