diff --git a/src/Symfony/Component/Messenger/Asynchronous/Middleware/SendMessageMiddleware.php b/src/Symfony/Component/Messenger/Asynchronous/Middleware/SendMessageMiddleware.php index 9e7dc9baef42f..ef2ce61009515 100644 --- a/src/Symfony/Component/Messenger/Asynchronous/Middleware/SendMessageMiddleware.php +++ b/src/Symfony/Component/Messenger/Asynchronous/Middleware/SendMessageMiddleware.php @@ -15,14 +15,13 @@ use Symfony\Component\Messenger\Asynchronous\Routing\SenderLocatorInterface; use Symfony\Component\Messenger\Asynchronous\Transport\ReceivedMessage; use Symfony\Component\Messenger\Envelope; -use Symfony\Component\Messenger\EnvelopeAwareInterface; use Symfony\Component\Messenger\Middleware\MiddlewareInterface; /** * @author Samuel Roze * @author Tobias Schultze */ -class SendMessageMiddleware implements MiddlewareInterface, EnvelopeAwareInterface +class SendMessageMiddleware implements MiddlewareInterface { private $senderLocator; private $messagesToSendAndHandleMapping; @@ -34,32 +33,28 @@ public function __construct(SenderLocatorInterface $senderLocator, array $messag } /** - * @param Envelope $envelope - * * {@inheritdoc} */ - public function handle($envelope, callable $next) + public function handle(Envelope $envelope, callable $next): void { if ($envelope->get(ReceivedMessage::class)) { // It's a received message. Do not send it back: - return $next($envelope); + $next($envelope); + + return; } - $sender = $this->senderLocator->getSenderForMessage($envelope->getMessage()); + $sender = $this->senderLocator->getSender($envelope); if ($sender) { $sender->send($envelope); - if (!$this->mustSendAndHandle($envelope->getMessage())) { + if (!AbstractSenderLocator::getValueFromMessageRouting($this->messagesToSendAndHandleMapping, $envelope)) { + // message has no corresponding handler return; } } - return $next($envelope); - } - - private function mustSendAndHandle($message): bool - { - return (bool) AbstractSenderLocator::getValueFromMessageRouting($this->messagesToSendAndHandleMapping, $message); + $next($envelope); } } diff --git a/src/Symfony/Component/Messenger/Asynchronous/Routing/AbstractSenderLocator.php b/src/Symfony/Component/Messenger/Asynchronous/Routing/AbstractSenderLocator.php index eafdd1de9f007..e812c151c4d2b 100644 --- a/src/Symfony/Component/Messenger/Asynchronous/Routing/AbstractSenderLocator.php +++ b/src/Symfony/Component/Messenger/Asynchronous/Routing/AbstractSenderLocator.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Messenger\Asynchronous\Routing; +use Symfony\Component\Messenger\Envelope; + /** * @author Samuel Roze * @@ -18,21 +20,30 @@ */ abstract class AbstractSenderLocator implements SenderLocatorInterface { - public static function getValueFromMessageRouting(array $mapping, $message) + public static function getValueFromMessageRouting(array $mapping, Envelope $envelope) { - if (isset($mapping[\get_class($message)])) { - return $mapping[\get_class($message)]; + $name = $envelope->getMessageName(); + + if (null !== $name && isset($mapping[$name])) { + return $mapping[$name]; } - if ($parentsMapping = array_intersect_key($mapping, class_parents($message))) { - return current($parentsMapping); + + if (isset($mapping[$class = \get_class($envelope->getMessage())])) { + return $mapping[$class]; } - if ($interfaceMapping = array_intersect_key($mapping, class_implements($message))) { - return current($interfaceMapping); + + foreach (class_parents($class) as $name) { + if (isset($mapping[$name])) { + return $mapping[$name]; + } } - if (isset($mapping['*'])) { - return $mapping['*']; + + foreach (class_implements($class) as $name) { + if (isset($mapping[$name])) { + return $mapping[$name]; + } } - return null; + return $mapping['*'] ?? null; } } diff --git a/src/Symfony/Component/Messenger/Asynchronous/Routing/ContainerSenderLocator.php b/src/Symfony/Component/Messenger/Asynchronous/Routing/ContainerSenderLocator.php index ef338bd5066b8..17113e4720328 100644 --- a/src/Symfony/Component/Messenger/Asynchronous/Routing/ContainerSenderLocator.php +++ b/src/Symfony/Component/Messenger/Asynchronous/Routing/ContainerSenderLocator.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Messenger\Asynchronous\Routing; use Psr\Container\ContainerInterface; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Transport\SenderInterface; /** @@ -31,9 +32,9 @@ public function __construct(ContainerInterface $senderServiceLocator, array $mes /** * {@inheritdoc} */ - public function getSenderForMessage($message): ?SenderInterface + public function getSender(Envelope $envelope): ?SenderInterface { - $senderId = self::getValueFromMessageRouting($this->messageToSenderIdMapping, $message); + $senderId = self::getValueFromMessageRouting($this->messageToSenderIdMapping, $envelope); return $senderId ? $this->senderServiceLocator->get($senderId) : null; } diff --git a/src/Symfony/Component/Messenger/Asynchronous/Routing/SenderLocator.php b/src/Symfony/Component/Messenger/Asynchronous/Routing/SenderLocator.php index 8c8b6b8a75a2f..f3ab3e8025296 100644 --- a/src/Symfony/Component/Messenger/Asynchronous/Routing/SenderLocator.php +++ b/src/Symfony/Component/Messenger/Asynchronous/Routing/SenderLocator.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Messenger\Asynchronous\Routing; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Exception\RuntimeException; use Symfony\Component\Messenger\Transport\SenderInterface; @@ -29,15 +30,15 @@ public function __construct(array $messageToSenderMapping) /** * {@inheritdoc} */ - public function getSenderForMessage($message): ?SenderInterface + public function getSender(Envelope $envelope): ?SenderInterface { - $sender = self::getValueFromMessageRouting($this->messageToSenderMapping, $message); + $sender = self::getValueFromMessageRouting($this->messageToSenderMapping, $envelope); if (null === $sender) { return null; } if (!$sender instanceof SenderInterface) { - throw new RuntimeException(sprintf('The sender instance provided for message "%s" should be of type "%s" but got "%s".', \get_class($message), SenderInterface::class, \is_object($sender) ? \get_class($sender) : \gettype($sender))); + throw new RuntimeException(sprintf('The sender instance provided for message "%s" should be of type "%s" but got "%s".', $envelope->getMessageName() ?? \get_class($envelope->getMessage()), SenderInterface::class, \is_object($sender) ? \get_class($sender) : \gettype($sender))); } return $sender; diff --git a/src/Symfony/Component/Messenger/Asynchronous/Routing/SenderLocatorInterface.php b/src/Symfony/Component/Messenger/Asynchronous/Routing/SenderLocatorInterface.php index 4380ab9962d41..d532ee8789da2 100644 --- a/src/Symfony/Component/Messenger/Asynchronous/Routing/SenderLocatorInterface.php +++ b/src/Symfony/Component/Messenger/Asynchronous/Routing/SenderLocatorInterface.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Messenger\Asynchronous\Routing; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Transport\SenderInterface; /** @@ -21,10 +22,6 @@ interface SenderLocatorInterface { /** * Gets the sender (if applicable) for the given message object. - * - * @param object $message - * - * @return SenderInterface|null */ - public function getSenderForMessage($message): ?SenderInterface; + public function getSender(Envelope $envelope): ?SenderInterface; } diff --git a/src/Symfony/Component/Messenger/CHANGELOG.md b/src/Symfony/Component/Messenger/CHANGELOG.md index 2abdada660a86..ae3ad106295d0 100644 --- a/src/Symfony/Component/Messenger/CHANGELOG.md +++ b/src/Symfony/Component/Messenger/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG ----- * The component is not experimental anymore + * [BC BREAK] `MessageBusInterface::dispatch()` and `MiddlewareInterface::handle()` now return `void` * [BC BREAK] The signature of `Amqp*` classes changed to take a `Connection` as a first argument and an optional `Serializer` as a second argument. * [BC BREAK] `SenderLocator` has been renamed to `ContainerSenderLocator` @@ -19,6 +20,12 @@ CHANGELOG * [BC BREAK] The `EncoderInterface` and `DecoderInterface` have been replaced by a unified `Symfony\Component\Messenger\Transport\Serialization\SerializerInterface`. * [BC BREAK] The locator passed to `ContainerHandlerLocator` should not prefix its keys by "handler." anymore * [BC BREAK] The `AbstractHandlerLocator::getHandler()` method uses `?callable` as return type + * [BC BREAK] `SenderLocatorInterface::getSenderForMessage()` has been replaced by `getSender(Envelope $envelope)` + * [BC BREAK] `MessengerDataCollector::getMessages()` returns an iterable, not just an array anymore + * [BC BREAK] `AbstractHandlerLocator` is now internal + * [BC BREAK] `HandlerLocatorInterface::resolve()` has been replaced by `getHandler(Envelope $envelope, bool $allowNoHandler = false)` + * [BC BREAK] `SenderLocatorInterface::getSenderForMessage()` has been replaced by `getSender(Envelope $envelope)` + * [BC BREAK] `SenderInterface::send()` returns `void` 4.1.0 ----- diff --git a/src/Symfony/Component/Messenger/DataCollector/MessengerDataCollector.php b/src/Symfony/Component/Messenger/DataCollector/MessengerDataCollector.php index 6713525ddf07f..33e39af03ddc3 100644 --- a/src/Symfony/Component/Messenger/DataCollector/MessengerDataCollector.php +++ b/src/Symfony/Component/Messenger/DataCollector/MessengerDataCollector.php @@ -17,7 +17,6 @@ use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface; use Symfony\Component\Messenger\TraceableMessageBus; use Symfony\Component\VarDumper\Caster\ClassStub; -use Symfony\Component\VarDumper\Cloner\Data; /** * @author Samuel Roze @@ -55,14 +54,10 @@ public function lateCollect() } // Order by call time - usort($messages, function (array $a, array $b): int { - return $a[1] > $b[1] ? 1 : -1; - }); + usort($messages, function ($a, $b) { return $a[1] <=> $b[1]; }); // Keep the messages clones only - $this->data['messages'] = array_map(function (array $item): Data { - return $item[0]; - }, $messages); + $this->data['messages'] = array_column($messages, 0); } /** @@ -98,14 +93,6 @@ private function collectMessage(string $busName, array $tracedMessage) 'caller' => $tracedMessage['caller'], ); - if (array_key_exists('result', $tracedMessage)) { - $result = $tracedMessage['result']; - $debugRepresentation['result'] = array( - 'type' => \is_object($result) ? \get_class($result) : \gettype($result), - 'value' => $result, - ); - } - if (isset($tracedMessage['exception'])) { $exception = $tracedMessage['exception']; @@ -120,18 +107,21 @@ private function collectMessage(string $busName, array $tracedMessage) public function getExceptionsCount(string $bus = null): int { - return array_reduce($this->getMessages($bus), function (int $carry, Data $message) { - return $carry += isset($message['exception']) ? 1 : 0; - }, 0); + $count = 0; + foreach ($this->getMessages($bus) as $message) { + $count += (int) isset($message['exception']); + } + + return $count; } - public function getMessages(string $bus = null): array + public function getMessages(string $bus = null): iterable { - $messages = $this->data['messages'] ?? array(); - - return $bus ? array_filter($messages, function (Data $message) use ($bus): bool { - return $bus === $message['bus']; - }) : $messages; + foreach ($this->data['messages'] ?? array() as $message) { + if (null === $bus || $bus === $message['bus']) { + yield $message; + } + } } public function getBuses(): array diff --git a/src/Symfony/Component/Messenger/Envelope.php b/src/Symfony/Component/Messenger/Envelope.php index 491179def87b6..e3df09728a1bb 100644 --- a/src/Symfony/Component/Messenger/Envelope.php +++ b/src/Symfony/Component/Messenger/Envelope.php @@ -27,6 +27,9 @@ final class Envelope */ public function __construct($message, array $items = array()) { + if (!\is_object($message)) { + throw new \TypeError(sprintf('Invalid argument provided to "%s()": expected object but got %s.', __METHOD__, \gettype($message))); + } $this->message = $message; foreach ($items as $item) { $this->items[\get_class($item)] = $item; @@ -38,9 +41,15 @@ public function __construct($message, array $items = array()) * * @param Envelope|object $message */ - public static function wrap($message): self + public static function wrap($message, string $name = null): self { - return $message instanceof self ? $message : new self($message); + $envelope = $message instanceof self ? clone $message : new self($message); + if (null !== $name) { + return $envelope->with(new MessageConfiguration($name)); + } + unset($envelope->items[MessageConfiguration::class]); + + return $envelope; } /** @@ -55,15 +64,6 @@ public function with(EnvelopeItemInterface $item): self return $cloned; } - public function withMessage($message): self - { - $cloned = clone $this; - - $cloned->message = $message; - - return $cloned; - } - public function get(string $itemFqcn): ?EnvelopeItemInterface { return $this->items[$itemFqcn] ?? null; @@ -85,14 +85,10 @@ public function getMessage() return $this->message; } - /** - * @param object $target - * - * @return Envelope|object The original message or the envelope if the target supports it - * (i.e implements {@link EnvelopeAwareInterface}). - */ - public function getMessageFor($target) + public function getMessageName(): ?string { - return $target instanceof EnvelopeAwareInterface ? $this : $this->message; + $config = $this->items[MessageConfiguration::class] ?? null; + + return $config ? $config->getName() : null; } } diff --git a/src/Symfony/Component/Messenger/EnvelopeAwareInterface.php b/src/Symfony/Component/Messenger/EnvelopeAwareInterface.php deleted file mode 100644 index bca44385bdc45..0000000000000 --- a/src/Symfony/Component/Messenger/EnvelopeAwareInterface.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Messenger; - -/** - * A Messenger protagonist aware of the message envelope and its content. - * - * @author Maxime Steinhausser - */ -interface EnvelopeAwareInterface -{ -} diff --git a/src/Symfony/Component/Messenger/Handler/ChainHandler.php b/src/Symfony/Component/Messenger/Handler/ChainHandler.php index c21d492e03217..b583366f2abc5 100644 --- a/src/Symfony/Component/Messenger/Handler/ChainHandler.php +++ b/src/Symfony/Component/Messenger/Handler/ChainHandler.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Messenger\Handler; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Exception\InvalidArgumentException; /** @@ -30,21 +31,19 @@ class ChainHandler */ public function __construct(array $handlers) { - if (empty($handlers)) { + if (!$handlers) { throw new InvalidArgumentException('A collection of message handlers requires at least one handler.'); } $this->handlers = $handlers; } - public function __invoke($message) + public function __invoke(Envelope $envelope) { - $results = array(); + $message = $envelope->getMessage(); foreach ($this->handlers as $handler) { - $results[] = $handler($message); + $handler($message); } - - return $results; } } diff --git a/src/Symfony/Component/Messenger/Handler/Locator/AbstractHandlerLocator.php b/src/Symfony/Component/Messenger/Handler/Locator/AbstractHandlerLocator.php index 6fecd1bd67cbc..3cf99806258d0 100644 --- a/src/Symfony/Component/Messenger/Handler/Locator/AbstractHandlerLocator.php +++ b/src/Symfony/Component/Messenger/Handler/Locator/AbstractHandlerLocator.php @@ -11,36 +11,46 @@ namespace Symfony\Component\Messenger\Handler\Locator; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Exception\NoHandlerForMessageException; /** * @author Miha Vrhovnik * @author Samuel Roze + * + * @internal */ abstract class AbstractHandlerLocator implements HandlerLocatorInterface { - public function resolve($message): callable + public function getHandler(Envelope $envelope, bool $allowNoHandler = false): ?callable { - $class = \get_class($message); + $name = $envelope->getMessageName(); - if ($handler = $this->getHandler($class)) { + if (null !== $name && $handler = $this->getHandlerByName($name)) { return $handler; } + $class = \get_class($envelope->getMessage()); - foreach (class_implements($class, false) as $interface) { - if ($handler = $this->getHandler($interface)) { + if ($handler = $this->getHandlerByName($class)) { + return $handler; + } + + foreach (class_implements($class) as $name) { + if ($handler = $this->getHandlerByName($name)) { return $handler; } } - foreach (class_parents($class, false) as $parent) { - if ($handler = $this->getHandler($parent)) { + foreach (class_parents($class) as $name) { + if ($handler = $this->getHandlerByName($name)) { return $handler; } } - throw new NoHandlerForMessageException(sprintf('No handler for message "%s".', $class)); + if (!$allowNoHandler) { + throw new NoHandlerForMessageException(sprintf('No handler for message "%s".', $class)); + } } - abstract protected function getHandler(string $class): ?callable; + abstract protected function getHandlerByName(string $name): ?callable; } diff --git a/src/Symfony/Component/Messenger/Handler/Locator/ContainerHandlerLocator.php b/src/Symfony/Component/Messenger/Handler/Locator/ContainerHandlerLocator.php index e9bc7ff5e69ef..0e1837f896abe 100644 --- a/src/Symfony/Component/Messenger/Handler/Locator/ContainerHandlerLocator.php +++ b/src/Symfony/Component/Messenger/Handler/Locator/ContainerHandlerLocator.php @@ -29,8 +29,8 @@ public function __construct(ContainerInterface $container) /** * {@inheritdoc} */ - protected function getHandler(string $class): ?callable + protected function getHandlerByName(string $name): ?callable { - return $this->container->has($class) ? $this->container->get($class) : null; + return $this->container->has($name) ? $this->container->get($name) : null; } } diff --git a/src/Symfony/Component/Messenger/Handler/Locator/HandlerLocator.php b/src/Symfony/Component/Messenger/Handler/Locator/HandlerLocator.php index ea6d0e2b419b4..4042ca682bcbf 100644 --- a/src/Symfony/Component/Messenger/Handler/Locator/HandlerLocator.php +++ b/src/Symfony/Component/Messenger/Handler/Locator/HandlerLocator.php @@ -29,8 +29,8 @@ public function __construct(array $messageToHandlerMapping = array()) /** * {@inheritdoc} */ - protected function getHandler(string $class): ?callable + protected function getHandlerByName(string $name): ?callable { - return $this->messageToHandlerMapping[$class] ?? null; + return $this->messageToHandlerMapping[$name] ?? null; } } diff --git a/src/Symfony/Component/Messenger/Handler/Locator/HandlerLocatorInterface.php b/src/Symfony/Component/Messenger/Handler/Locator/HandlerLocatorInterface.php index 131c3ce623d8c..e3b95ab182a49 100644 --- a/src/Symfony/Component/Messenger/Handler/Locator/HandlerLocatorInterface.php +++ b/src/Symfony/Component/Messenger/Handler/Locator/HandlerLocatorInterface.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Messenger\Handler\Locator; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Exception\NoHandlerForMessageException; /** @@ -21,11 +22,7 @@ interface HandlerLocatorInterface /** * Returns the handler for the given message. * - * @param object $message - * - * @throws NoHandlerForMessageException - * - * @return callable + * @throws NoHandlerForMessageException When no handler is found and $allowNoHandler is false */ - public function resolve($message): callable; + public function getHandler(Envelope $envelope, bool $allowNoHandler = false): ?callable; } diff --git a/src/Symfony/Component/Messenger/MessageBus.php b/src/Symfony/Component/Messenger/MessageBus.php index 89fa8e04fa23c..70ed377fca9d5 100644 --- a/src/Symfony/Component/Messenger/MessageBus.php +++ b/src/Symfony/Component/Messenger/MessageBus.php @@ -11,67 +11,52 @@ namespace Symfony\Component\Messenger; -use Symfony\Component\Messenger\Exception\InvalidArgumentException; use Symfony\Component\Messenger\Middleware\MiddlewareInterface; /** * @author Samuel Roze * @author Matthias Noback + * @author Nicolas Grekas */ class MessageBus implements MessageBusInterface { - private $middlewareHandlers; - - /** - * @var MiddlewareInterface[]|null - */ - private $indexedMiddlewareHandlers; + private $middlewareAggregate; /** * @param MiddlewareInterface[]|iterable $middlewareHandlers */ public function __construct(iterable $middlewareHandlers = array()) { - $this->middlewareHandlers = $middlewareHandlers; + if ($middlewareHandlers instanceof \IteratorAggregate) { + $this->middlewareAggregate = $middlewareHandlers; + } elseif (\is_array($middlewareHandlers)) { + $this->middlewareAggregate = new \ArrayObject($middlewareHandlers); + } else { + $this->middlewareAggregate = new \ArrayObject(iterator_to_array($middlewareHandlers, false)); + } } /** * {@inheritdoc} */ - public function dispatch($message) + public function dispatch($message, string $name = null): void { if (!\is_object($message)) { - throw new InvalidArgumentException(sprintf('Invalid type for message argument. Expected object, but got "%s".', \gettype($message))); - } - - return \call_user_func($this->callableForNextMiddleware(0, Envelope::wrap($message)), $message); - } - - private function callableForNextMiddleware(int $index, Envelope $currentEnvelope): callable - { - if (null === $this->indexedMiddlewareHandlers) { - $this->indexedMiddlewareHandlers = \is_array($this->middlewareHandlers) ? array_values($this->middlewareHandlers) : iterator_to_array($this->middlewareHandlers, false); + throw new \TypeError(sprintf('Invalid argument provided to "%s()": expected object, but got %s.', __METHOD__, \gettype($message))); } - if (!isset($this->indexedMiddlewareHandlers[$index])) { - return function () {}; - } - - $middleware = $this->indexedMiddlewareHandlers[$index]; + $middlewareIterator = $this->middlewareAggregate->getIterator(); - return function ($message) use ($middleware, $index, $currentEnvelope) { - if ($message instanceof Envelope) { - $currentEnvelope = $message; - } else { - $message = $currentEnvelope->withMessage($message); - } + foreach ($middlewareIterator as $middleware) { + $next = static function ($envelope) use ($middlewareIterator, &$next) { + $middlewareIterator->next(); - if (!$middleware instanceof EnvelopeAwareInterface) { - // Do not provide the envelope if the middleware cannot read it: - $message = $message->getMessage(); - } + if ($middlewareIterator->valid()) { + $middlewareIterator->current()->handle($envelope, $next); + } + }; - return $middleware->handle($message, $this->callableForNextMiddleware($index + 1, $currentEnvelope)); - }; + $middleware->handle(Envelope::wrap($message), $next); + } } } diff --git a/src/Symfony/Component/Messenger/MessageBusInterface.php b/src/Symfony/Component/Messenger/MessageBusInterface.php index c44b3dfbb5194..dd4ce4696b463 100644 --- a/src/Symfony/Component/Messenger/MessageBusInterface.php +++ b/src/Symfony/Component/Messenger/MessageBusInterface.php @@ -19,11 +19,9 @@ interface MessageBusInterface /** * Dispatches the given message. * - * The bus can return a value coming from handlers, but is not required to do so. - * * @param object|Envelope $message The message or the message pre-wrapped in an envelope - * - * @return mixed + * @param string|null $name The name to use as dispatching key; when not provided, + * this name is derived from the type of the message */ - public function dispatch($message); + public function dispatch($message, string $name = null): void; } diff --git a/src/Symfony/Component/Messenger/MessageConfiguration.php b/src/Symfony/Component/Messenger/MessageConfiguration.php new file mode 100644 index 0000000000000..3c07d70bfec70 --- /dev/null +++ b/src/Symfony/Component/Messenger/MessageConfiguration.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Messenger; + +/** + * @author Nicolas Grekas + */ +final class MessageConfiguration implements EnvelopeItemInterface +{ + private $name; + + public function __construct(string $name) + { + $this->name = $name; + } + + public function getName(): string + { + return $this->name; + } +} diff --git a/src/Symfony/Component/Messenger/Middleware/AllowNoHandlerMiddleware.php b/src/Symfony/Component/Messenger/Middleware/AllowNoHandlerMiddleware.php deleted file mode 100644 index 33494548f832f..0000000000000 --- a/src/Symfony/Component/Messenger/Middleware/AllowNoHandlerMiddleware.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Messenger\Middleware; - -use Symfony\Component\Messenger\Exception\NoHandlerForMessageException; - -/** - * @author Samuel Roze - */ -class AllowNoHandlerMiddleware implements MiddlewareInterface -{ - public function handle($message, callable $next) - { - try { - return $next($message); - } catch (NoHandlerForMessageException $e) { - // We allow not having a handler for this message. - } - } -} diff --git a/src/Symfony/Component/Messenger/Middleware/Enhancers/ActivationMiddlewareDecorator.php b/src/Symfony/Component/Messenger/Middleware/Enhancers/ActivationMiddlewareDecorator.php index c9244acbc4bbb..683f3e57616f7 100644 --- a/src/Symfony/Component/Messenger/Middleware/Enhancers/ActivationMiddlewareDecorator.php +++ b/src/Symfony/Component/Messenger/Middleware/Enhancers/ActivationMiddlewareDecorator.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Messenger\Middleware\Enhancers; use Symfony\Component\Messenger\Envelope; -use Symfony\Component\Messenger\EnvelopeAwareInterface; use Symfony\Component\Messenger\Middleware\MiddlewareInterface; /** @@ -20,7 +19,7 @@ * * @author Maxime Steinhausser */ -class ActivationMiddlewareDecorator implements MiddlewareInterface, EnvelopeAwareInterface +class ActivationMiddlewareDecorator implements MiddlewareInterface { private $inner; private $activated; @@ -35,14 +34,14 @@ public function __construct(MiddlewareInterface $inner, $activated) } /** - * @param Envelope $envelope + * {@inheritdoc} */ - public function handle($envelope, callable $next) + public function handle(Envelope $envelope, callable $next): void { if (\is_callable($this->activated) ? ($this->activated)($envelope) : $this->activated) { - return $this->inner->handle($envelope->getMessageFor($this->inner), $next); + $this->inner->handle($envelope, $next); + } else { + $next($envelope); } - - return $next($envelope); } } diff --git a/src/Symfony/Component/Messenger/Middleware/Enhancers/TraceableMiddleware.php b/src/Symfony/Component/Messenger/Middleware/Enhancers/TraceableMiddleware.php index 61cbca8c23cab..9d4ea255ef792 100644 --- a/src/Symfony/Component/Messenger/Middleware/Enhancers/TraceableMiddleware.php +++ b/src/Symfony/Component/Messenger/Middleware/Enhancers/TraceableMiddleware.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Messenger\Middleware\Enhancers; use Symfony\Component\Messenger\Envelope; -use Symfony\Component\Messenger\EnvelopeAwareInterface; use Symfony\Component\Messenger\Middleware\MiddlewareInterface; use Symfony\Component\Stopwatch\Stopwatch; @@ -21,7 +20,7 @@ * * @author Maxime Steinhausser */ -class TraceableMiddleware implements MiddlewareInterface, EnvelopeAwareInterface +class TraceableMiddleware implements MiddlewareInterface { private $inner; private $stopwatch; @@ -37,9 +36,9 @@ public function __construct(MiddlewareInterface $inner, Stopwatch $stopwatch, st } /** - * @param Envelope $envelope + * {@inheritdoc} */ - public function handle($envelope, callable $next) + public function handle(Envelope $envelope, callable $next): void { $class = \get_class($this->inner); $eventName = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; @@ -51,19 +50,15 @@ public function handle($envelope, callable $next) $this->stopwatch->start($eventName, $this->eventCategory); try { - $result = $this->inner->handle($envelope->getMessageFor($this->inner), function ($message) use ($next, $eventName) { + $this->inner->handle($envelope, function (Envelope $envelope) use ($next, $eventName) { $this->stopwatch->stop($eventName); - $result = $next($message); + $next($envelope); $this->stopwatch->start($eventName, $this->eventCategory); - - return $result; }); } finally { if ($this->stopwatch->isStarted($eventName)) { $this->stopwatch->stop($eventName); } } - - return $result; } } diff --git a/src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php b/src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php index 4d63a8ae6c5a4..954124ee9010a 100644 --- a/src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php +++ b/src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Messenger\Middleware; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Handler\Locator\HandlerLocatorInterface; /** @@ -18,23 +19,20 @@ */ class HandleMessageMiddleware implements MiddlewareInterface { - private $messageHandlerResolver; + private $messageHandlerLocator; - public function __construct(HandlerLocatorInterface $messageHandlerResolver) + public function __construct(HandlerLocatorInterface $messageHandlerLocator, bool $allowNoHandler = false) { - $this->messageHandlerResolver = $messageHandlerResolver; + $this->messageHandlerLocator = $messageHandlerLocator; + $this->allowNoHandler = $allowNoHandler; } - /** - * {@inheritdoc} - */ - public function handle($message, callable $next) + public function handle(Envelope $envelope, callable $next): void { - $handler = $this->messageHandlerResolver->resolve($message); - $result = $handler($message); + if ($handler = $this->messageHandlerLocator->getHandler($envelope, $this->allowNoHandler)) { + $handler($envelope->getMessage()); + } - $next($message); - - return $result; + $next($envelope); } } diff --git a/src/Symfony/Component/Messenger/Middleware/LoggingMiddleware.php b/src/Symfony/Component/Messenger/Middleware/LoggingMiddleware.php index ebaf8525c0407..de747a761fef3 100644 --- a/src/Symfony/Component/Messenger/Middleware/LoggingMiddleware.php +++ b/src/Symfony/Component/Messenger/Middleware/LoggingMiddleware.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Messenger\Middleware; use Psr\Log\LoggerInterface; +use Symfony\Component\Messenger\Envelope; /** * @author Samuel Roze @@ -28,31 +29,23 @@ public function __construct(LoggerInterface $logger) /** * {@inheritdoc} */ - public function handle($message, callable $next) + public function handle(Envelope $envelope, callable $next): void { - $this->logger->debug('Starting handling message {class}', $this->createContext($message)); + $context = array( + 'message' => $envelope->getMessage(), + 'name' => $envelope->getMessageName() ?? \get_class($envelope->getMessage()), + ); + $this->logger->debug('Starting handling message {name}', $context); try { - $result = $next($message); + $next($envelope); } catch (\Throwable $e) { - $this->logger->warning('An exception occurred while handling message {class}', array_merge( - $this->createContext($message), - array('exception' => $e) - )); + $context['exception'] = $e; + $this->logger->warning('An exception occurred while handling message {name}', $context); throw $e; } - $this->logger->debug('Finished handling message {class}', $this->createContext($message)); - - return $result; - } - - private function createContext($message): array - { - return array( - 'message' => $message, - 'class' => \get_class($message), - ); + $this->logger->debug('Finished handling message {name}', $context); } } diff --git a/src/Symfony/Component/Messenger/Middleware/MiddlewareInterface.php b/src/Symfony/Component/Messenger/Middleware/MiddlewareInterface.php index 0d1c3e29e497e..d8a268959d0fd 100644 --- a/src/Symfony/Component/Messenger/Middleware/MiddlewareInterface.php +++ b/src/Symfony/Component/Messenger/Middleware/MiddlewareInterface.php @@ -11,15 +11,12 @@ namespace Symfony\Component\Messenger\Middleware; +use Symfony\Component\Messenger\Envelope; + /** * @author Samuel Roze */ interface MiddlewareInterface { - /** - * @param object $message - * - * @return mixed - */ - public function handle($message, callable $next); + public function handle(Envelope $envelope, callable $next): void; } diff --git a/src/Symfony/Component/Messenger/Middleware/ValidationMiddleware.php b/src/Symfony/Component/Messenger/Middleware/ValidationMiddleware.php index 9f6f82e33c2bf..aaabed3c1fbcd 100644 --- a/src/Symfony/Component/Messenger/Middleware/ValidationMiddleware.php +++ b/src/Symfony/Component/Messenger/Middleware/ValidationMiddleware.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Messenger\Middleware; use Symfony\Component\Messenger\Envelope; -use Symfony\Component\Messenger\EnvelopeAwareInterface; use Symfony\Component\Messenger\Exception\ValidationFailedException; use Symfony\Component\Messenger\Middleware\Configuration\ValidationConfiguration; use Symfony\Component\Validator\Validator\ValidatorInterface; @@ -20,7 +19,7 @@ /** * @author Tobias Nyholm */ -class ValidationMiddleware implements MiddlewareInterface, EnvelopeAwareInterface +class ValidationMiddleware implements MiddlewareInterface { private $validator; @@ -30,9 +29,9 @@ public function __construct(ValidatorInterface $validator) } /** - * @param Envelope $envelope + * {@inheritdoc} */ - public function handle($envelope, callable $next) + public function handle(Envelope $envelope, callable $next): void { $message = $envelope->getMessage(); $groups = null; @@ -46,6 +45,6 @@ public function handle($envelope, callable $next) throw new ValidationFailedException($message, $violations); } - return $next($envelope); + $next($envelope); } } diff --git a/src/Symfony/Component/Messenger/Tests/Asynchronous/Middleware/SendMessageMiddlewareTest.php b/src/Symfony/Component/Messenger/Tests/Asynchronous/Middleware/SendMessageMiddlewareTest.php index 91d4bbeea15bd..7c0a8ae7a94e5 100644 --- a/src/Symfony/Component/Messenger/Tests/Asynchronous/Middleware/SendMessageMiddlewareTest.php +++ b/src/Symfony/Component/Messenger/Tests/Asynchronous/Middleware/SendMessageMiddlewareTest.php @@ -158,7 +158,7 @@ public function __construct(?SenderInterface $sender) $this->sender = $sender; } - public function getSenderForMessage($message): ?SenderInterface + public function getSender(Envelope $envelope): ?SenderInterface { return $this->sender; } diff --git a/src/Symfony/Component/Messenger/Tests/Asynchronous/Routing/ContainerSenderLocatorTest.php b/src/Symfony/Component/Messenger/Tests/Asynchronous/Routing/ContainerSenderLocatorTest.php index 29eac0f05617e..df8df34e0dff2 100644 --- a/src/Symfony/Component/Messenger/Tests/Asynchronous/Routing/ContainerSenderLocatorTest.php +++ b/src/Symfony/Component/Messenger/Tests/Asynchronous/Routing/ContainerSenderLocatorTest.php @@ -14,6 +14,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\Messenger\Asynchronous\Routing\ContainerSenderLocator; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Tests\Fixtures\ChildDummyMessage; use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage; use Symfony\Component\Messenger\Tests\Fixtures\DummyMessageInterface; @@ -32,8 +33,8 @@ public function testItReturnsTheSenderBasedOnTheMessageClass() DummyMessage::class => 'my_amqp_sender', )); - $this->assertSame($sender, $locator->getSenderForMessage(new DummyMessage('Hello'))); - $this->assertNull($locator->getSenderForMessage(new SecondMessage())); + $this->assertSame($sender, $locator->getSender(new Envelope(new DummyMessage('Hello')))); + $this->assertNull($locator->getSender(new Envelope(new SecondMessage()))); } public function testItReturnsTheSenderBasedOnTheMessageParentClass() @@ -51,8 +52,8 @@ public function testItReturnsTheSenderBasedOnTheMessageParentClass() DummyMessage::class => 'my_amqp_sender', )); - $this->assertSame($sender, $locator->getSenderForMessage(new ChildDummyMessage('Hello'))); - $this->assertNull($locator->getSenderForMessage(new SecondMessage())); + $this->assertSame($sender, $locator->getSender(new Envelope(new ChildDummyMessage('Hello')))); + $this->assertNull($locator->getSender(new Envelope(new SecondMessage()))); } public function testItReturnsTheSenderBasedOnTheMessageInterface() @@ -66,8 +67,8 @@ public function testItReturnsTheSenderBasedOnTheMessageInterface() DummyMessageInterface::class => 'my_amqp_sender', )); - $this->assertSame($sender, $locator->getSenderForMessage(new DummyMessage('Hello'))); - $this->assertNull($locator->getSenderForMessage(new SecondMessage())); + $this->assertSame($sender, $locator->getSender(new Envelope(new DummyMessage('Hello')))); + $this->assertNull($locator->getSender(new Envelope(new SecondMessage()))); } public function testItSupportsAWildcardInsteadOfTheMessageClass() @@ -85,7 +86,7 @@ public function testItSupportsAWildcardInsteadOfTheMessageClass() '*' => 'my_api_sender', )); - $this->assertSame($sender, $locator->getSenderForMessage(new DummyMessage('Hello'))); - $this->assertSame($apiSender, $locator->getSenderForMessage(new SecondMessage())); + $this->assertSame($sender, $locator->getSender(new Envelope(new DummyMessage('Hello')))); + $this->assertSame($apiSender, $locator->getSender(new Envelope(new SecondMessage()))); } } diff --git a/src/Symfony/Component/Messenger/Tests/Asynchronous/Routing/SenderLocatorTest.php b/src/Symfony/Component/Messenger/Tests/Asynchronous/Routing/SenderLocatorTest.php index f39a31617a7ab..436d6021b28c8 100644 --- a/src/Symfony/Component/Messenger/Tests/Asynchronous/Routing/SenderLocatorTest.php +++ b/src/Symfony/Component/Messenger/Tests/Asynchronous/Routing/SenderLocatorTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Messenger\Asynchronous\Routing\SenderLocator; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Exception\RuntimeException; use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage; use Symfony\Component\Messenger\Tests\Fixtures\SecondMessage; @@ -27,8 +28,8 @@ public function testItReturnsTheSenderBasedOnTheMessageClass() DummyMessage::class => $sender, )); - $this->assertSame($sender, $locator->getSenderForMessage(new DummyMessage('Hello'))); - $this->assertNull($locator->getSenderForMessage(new SecondMessage())); + $this->assertSame($sender, $locator->getSender(new Envelope(new DummyMessage('Hello')))); + $this->assertNull($locator->getSender(new Envelope(new SecondMessage()))); } public function testItThrowsExceptionIfConfigurationIsWrong() @@ -38,6 +39,6 @@ public function testItThrowsExceptionIfConfigurationIsWrong() )); $this->expectException(RuntimeException::class); - $locator->getSenderForMessage(new DummyMessage('Hello')); + $locator->getSender(new Envelope(new DummyMessage('Hello'))); } } diff --git a/src/Symfony/Component/Messenger/Tests/DataCollector/MessengerDataCollectorTest.php b/src/Symfony/Component/Messenger/Tests/DataCollector/MessengerDataCollectorTest.php index 7c4fafa34090b..cfd5ce2b71b57 100644 --- a/src/Symfony/Component/Messenger/Tests/DataCollector/MessengerDataCollectorTest.php +++ b/src/Symfony/Component/Messenger/Tests/DataCollector/MessengerDataCollectorTest.php @@ -33,15 +33,12 @@ protected function setUp() $this->dumper->setColors(false); } - /** - * @dataProvider getHandleTestData - */ - public function testHandle($returnedValue, $expected) + public function testHandle() { $message = new DummyMessage('dummy message'); $bus = $this->getMockBuilder(MessageBusInterface::class)->getMock(); - $bus->method('dispatch')->with($message)->willReturn($returnedValue); + $bus->method('dispatch')->with($message); $bus = new TraceableMessageBus($bus); $collector = new MessengerDataCollector(); @@ -51,18 +48,14 @@ public function testHandle($returnedValue, $expected) $collector->lateCollect(); - $messages = $collector->getMessages(); + $messages = iterator_to_array($collector->getMessages()); $this->assertCount(1, $messages); - $this->assertStringMatchesFormat($expected, $this->getDataAsString($messages[0])); - } - - public function getHandleTestData() - { $file = __FILE__; - $messageDump = << "default" - "envelopeItems" => null + "envelopeItems" => [] "message" => array:2 [ "type" => "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage" "value" => Symfony\Component\Messenger\Tests\Fixtures\DummyMessage %A @@ -74,48 +67,10 @@ public function getHandleTestData() "file" => "$file" "line" => %d ] -DUMP; - - yield 'no returned value' => array( - null, - << array:2 [ - "type" => "NULL" - "value" => null - ] -] -DUMP - ); - - yield 'scalar returned value' => array( - 'returned value', - << array:2 [ - "type" => "string" - "value" => "returned value" - ] ] -DUMP - ); +DUMP; - yield 'array returned value' => array( - array('returned value'), - << array:2 [ - "type" => "array" - "value" => array:1 [ - 0 => "returned value" - ] - ] -] -DUMP - ); + $this->assertStringMatchesFormat($expected, $this->getDataAsString($messages[0])); } public function testHandleWithException() @@ -138,14 +93,14 @@ public function testHandleWithException() $collector->lateCollect(); - $messages = $collector->getMessages(); + $messages = iterator_to_array($collector->getMessages()); $this->assertCount(1, $messages); $file = __FILE__; $this->assertStringMatchesFormat(<< "default" - "envelopeItems" => null + "envelopeItems" => [] "message" => array:2 [ "type" => "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage" "value" => Symfony\Component\Messenger\Tests\Fixtures\DummyMessage %A @@ -186,7 +141,7 @@ public function testKeepsOrderedDispatchCalls() $collector->lateCollect(); - $messages = $collector->getMessages(); + $messages = iterator_to_array($collector->getMessages()); $this->assertCount(5, $messages); $this->assertSame('#1', $messages[0]['message']['value']['message']); diff --git a/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php b/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php index 9a81f3d951318..7edb269a65dc2 100644 --- a/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php +++ b/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php @@ -852,8 +852,8 @@ public function dummyMethodForSomeBus() class UselessMiddleware implements MiddlewareInterface { - public function handle($message, callable $next) + public function handle(Envelope $envelope, callable $next): void { - return $next($message); + $next($envelope); } } diff --git a/src/Symfony/Component/Messenger/Tests/EnvelopeTest.php b/src/Symfony/Component/Messenger/Tests/EnvelopeTest.php index 053275b6e714c..9432e88001ebf 100644 --- a/src/Symfony/Component/Messenger/Tests/EnvelopeTest.php +++ b/src/Symfony/Component/Messenger/Tests/EnvelopeTest.php @@ -14,7 +14,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Messenger\Asynchronous\Transport\ReceivedMessage; use Symfony\Component\Messenger\Envelope; -use Symfony\Component\Messenger\EnvelopeAwareInterface; use Symfony\Component\Messenger\Middleware\Configuration\ValidationConfiguration; use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage; @@ -76,7 +75,3 @@ public function testAll() $this->assertSame($validationConfig, $configs[ValidationConfiguration::class]); } } - -class FooConfigurationConsumer implements EnvelopeAwareInterface -{ -} diff --git a/src/Symfony/Component/Messenger/Tests/Handler/ChainHandlerTest.php b/src/Symfony/Component/Messenger/Tests/Handler/ChainHandlerTest.php index 5126697fb9df2..da28e8e15fd9d 100644 --- a/src/Symfony/Component/Messenger/Tests/Handler/ChainHandlerTest.php +++ b/src/Symfony/Component/Messenger/Tests/Handler/ChainHandlerTest.php @@ -12,33 +12,30 @@ namespace Symfony\Component\Messenger\Tests\Handler; use PHPUnit\Framework\TestCase; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Handler\ChainHandler; use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage; class ChainHandlerTest extends TestCase { - public function testItCallsTheHandlersAndReturnsAllResults() + public function testItCallsTheHandlers() { - $message = new DummyMessage('Hey'); + $message = new Envelope(new DummyMessage('Hey')); $handler1 = $this->createPartialMock(\stdClass::class, array('__invoke')); $handler1 ->expects($this->once()) ->method('__invoke') ->with($message) - ->willReturn('Hello') ; $handler2 = $this->createPartialMock(\stdClass::class, array('__invoke')); $handler2 ->expects($this->once()) ->method('__invoke') ->with($message) - ->willReturn('World') ; - $results = (new ChainHandler(array($handler1, $handler2)))($message); - - $this->assertSame(array('Hello', 'World'), $results); + (new ChainHandler(array($handler1, $handler2)))($message); } /** diff --git a/src/Symfony/Component/Messenger/Tests/Handler/Locator/ContainerHandlerLocatorTest.php b/src/Symfony/Component/Messenger/Tests/Handler/Locator/ContainerHandlerLocatorTest.php index 40eee2bd7e6a3..98680c329bc03 100644 --- a/src/Symfony/Component/Messenger/Tests/Handler/Locator/ContainerHandlerLocatorTest.php +++ b/src/Symfony/Component/Messenger/Tests/Handler/Locator/ContainerHandlerLocatorTest.php @@ -4,6 +4,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Handler\Locator\ContainerHandlerLocator; use Symfony\Component\Messenger\Tests\Fixtures\ChildDummyMessage; use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage; @@ -19,7 +20,7 @@ public function testItLocatesHandlerUsingTheMessageClass() $container->set(DummyMessage::class, $handler); $locator = new ContainerHandlerLocator($container); - $resolvedHandler = $locator->resolve(new DummyMessage('Hey')); + $resolvedHandler = $locator->getHandler(new Envelope(new DummyMessage('Hey'))); $this->assertSame($handler, $resolvedHandler); } @@ -31,10 +32,10 @@ public function testItLocatesHandlerUsingTheMessageClass() public function testThrowsNoHandlerException() { $locator = new ContainerHandlerLocator(new Container()); - $locator->resolve(new DummyMessage('Hey')); + $locator->getHandler(new Envelope(new DummyMessage('Hey'))); } - public function testResolveMessageViaTheirInterface() + public function testGetHandlerViaInterface() { $handler = function () {}; @@ -42,12 +43,12 @@ public function testResolveMessageViaTheirInterface() $container->set(DummyMessageInterface::class, $handler); $locator = new ContainerHandlerLocator($container); - $resolvedHandler = $locator->resolve(new DummyMessage('Hey')); + $resolvedHandler = $locator->getHandler(new Envelope(new DummyMessage('Hey'))); $this->assertSame($handler, $resolvedHandler); } - public function testResolveMessageViaTheirParentClass() + public function testGetHandlerViaParentClass() { $handler = function () {}; @@ -55,7 +56,7 @@ public function testResolveMessageViaTheirParentClass() $container->set(DummyMessage::class, $handler); $locator = new ContainerHandlerLocator($container); - $resolvedHandler = $locator->resolve(new ChildDummyMessage('Hey')); + $resolvedHandler = $locator->getHandler(new Envelope(new ChildDummyMessage('Hey'))); $this->assertSame($handler, $resolvedHandler); } diff --git a/src/Symfony/Component/Messenger/Tests/MessageBusTest.php b/src/Symfony/Component/Messenger/Tests/MessageBusTest.php index 9dc93a9d15213..a5c5eaa91e089 100644 --- a/src/Symfony/Component/Messenger/Tests/MessageBusTest.php +++ b/src/Symfony/Component/Messenger/Tests/MessageBusTest.php @@ -31,15 +31,15 @@ public function testItHasTheRightInterface() } /** - * @expectedException \Symfony\Component\Messenger\Exception\InvalidArgumentException - * @expectedExceptionMessage Invalid type for message argument. Expected object, but got "string". + * @expectedException \TypeError + * @expectedExceptionMessage Invalid argument provided to "Symfony\Component\Messenger\MessageBus::dispatch()": expected object, but got string. */ public function testItDispatchInvalidMessageType() { (new MessageBus())->dispatch('wrong'); } - public function testItCallsMiddlewareAndChainTheReturnValue() + public function testItCallsMiddleware() { $message = new DummyMessage('Hello'); $responseFromDepthMiddleware = 1234; @@ -49,21 +49,21 @@ public function testItCallsMiddlewareAndChainTheReturnValue() ->method('handle') ->with($message, $this->anything()) ->will($this->returnCallback(function ($message, $next) { - return $next($message); + $next($message); })); $secondMiddleware = $this->getMockBuilder(MiddlewareInterface::class)->getMock(); $secondMiddleware->expects($this->once()) ->method('handle') ->with($message, $this->anything()) - ->willReturn($responseFromDepthMiddleware); + ; $bus = new MessageBus(array( $firstMiddleware, $secondMiddleware, )); - $this->assertEquals($responseFromDepthMiddleware, $bus->dispatch($message)); + $bus->dispatch($message); } public function testItKeepsTheEnvelopeEvenThroughAMiddlewareThatIsNotEnvelopeAware() @@ -76,7 +76,7 @@ public function testItKeepsTheEnvelopeEvenThroughAMiddlewareThatIsNotEnvelopeAwa ->method('handle') ->with($message, $this->anything()) ->will($this->returnCallback(function ($message, $next) { - return $next($message); + $next($message); })); $secondMiddleware = $this->getMockBuilder(array(MiddlewareInterface::class, EnvelopeAwareInterface::class))->getMock(); @@ -104,7 +104,7 @@ public function testThatAMiddlewareCanAddSomeItemsToTheEnvelope() ->method('handle') ->with($envelope, $this->anything()) ->will($this->returnCallback(function ($message, $next) { - return $next($message->with(new AnEnvelopeItem())); + $next($message->with(new AnEnvelopeItem())); })); $secondMiddleware = $this->getMockBuilder(MiddlewareInterface::class)->getMock(); @@ -112,7 +112,7 @@ public function testThatAMiddlewareCanAddSomeItemsToTheEnvelope() ->method('handle') ->with($message, $this->anything()) ->will($this->returnCallback(function ($message, $next) { - return $next($message); + $next($message); })); $thirdMiddleware = $this->getMockBuilder(array(MiddlewareInterface::class, EnvelopeAwareInterface::class))->getMock(); @@ -143,7 +143,7 @@ public function testThatAMiddlewareCanUpdateTheMessageWhileKeepingTheEnvelopeIte ->method('handle') ->with($message, $this->anything()) ->will($this->returnCallback(function ($message, $next) use ($changedMessage) { - return $next($changedMessage); + $next($changedMessage); })); $secondMiddleware = $this->getMockBuilder(array(MiddlewareInterface::class, EnvelopeAwareInterface::class))->getMock(); diff --git a/src/Symfony/Component/Messenger/Tests/Middleware/AllowNoHandlerMiddlewareTest.php b/src/Symfony/Component/Messenger/Tests/Middleware/AllowNoHandlerMiddlewareTest.php index 74610d8029c70..efbefb9586a3f 100644 --- a/src/Symfony/Component/Messenger/Tests/Middleware/AllowNoHandlerMiddlewareTest.php +++ b/src/Symfony/Component/Messenger/Tests/Middleware/AllowNoHandlerMiddlewareTest.php @@ -18,15 +18,15 @@ class AllowNoHandlerMiddlewareTest extends TestCase { - public function testItCallsNextMiddlewareAndReturnsItsResult() + public function testItCallsNextMiddleware() { $message = new DummyMessage('Hey'); $next = $this->createPartialMock(\stdClass::class, array('__invoke')); - $next->expects($this->once())->method('__invoke')->with($message)->willReturn('Foo'); + $next->expects($this->once())->method('__invoke')->with($message); $middleware = new AllowNoHandlerMiddleware(); - $this->assertSame('Foo', $middleware->handle($message, $next)); + $middleware->handle($message, $next); } public function testItCatchesTheNoHandlerException() diff --git a/src/Symfony/Component/Messenger/Tests/Middleware/Enhancers/ActivationMiddlewareDecoratorTest.php b/src/Symfony/Component/Messenger/Tests/Middleware/Enhancers/ActivationMiddlewareDecoratorTest.php index 32b4a7d0f2fdf..6f7517808fb15 100644 --- a/src/Symfony/Component/Messenger/Tests/Middleware/Enhancers/ActivationMiddlewareDecoratorTest.php +++ b/src/Symfony/Component/Messenger/Tests/Middleware/Enhancers/ActivationMiddlewareDecoratorTest.php @@ -32,11 +32,11 @@ public function testExecuteMiddlewareOnActivated() $next->expects($this->never())->method('__invoke'); $middleware = $this->createMock(MiddlewareInterface::class); - $middleware->expects($this->once())->method('handle')->with($message, $next)->willReturn('Hello from middleware'); + $middleware->expects($this->once())->method('handle')->with($message, $next); $decorator = new ActivationMiddlewareDecorator($middleware, true); - $this->assertSame('Hello from middleware', $decorator->handle($envelope, $next)); + $decorator->handle($envelope, $next); } public function testExecuteMiddlewareOnActivatedWithCallable() @@ -51,11 +51,11 @@ public function testExecuteMiddlewareOnActivatedWithCallable() $next->expects($this->never())->method('__invoke'); $middleware = $this->createMock(MiddlewareInterface::class); - $middleware->expects($this->once())->method('handle')->with($message, $next)->willReturn('Hello from middleware'); + $middleware->expects($this->once())->method('handle')->with($message, $next); $decorator = new ActivationMiddlewareDecorator($middleware, $activated); - $this->assertSame('Hello from middleware', $decorator->handle($envelope, $next)); + $decorator->handle($envelope, $next); } public function testExecuteEnvelopeAwareMiddlewareWithEnvelope() @@ -67,11 +67,11 @@ public function testExecuteEnvelopeAwareMiddlewareWithEnvelope() $next->expects($this->never())->method('__invoke'); $middleware = $this->createMock(array(MiddlewareInterface::class, EnvelopeAwareInterface::class)); - $middleware->expects($this->once())->method('handle')->with($envelope, $next)->willReturn('Hello from middleware'); + $middleware->expects($this->once())->method('handle')->with($envelope, $next); $decorator = new ActivationMiddlewareDecorator($middleware, true); - $this->assertSame('Hello from middleware', $decorator->handle($envelope, $next)); + $decorator->handle($envelope, $next); } public function testExecuteMiddlewareOnDeactivated() @@ -80,13 +80,13 @@ public function testExecuteMiddlewareOnDeactivated() $envelope = Envelope::wrap($message); $next = $this->createPartialMock(\stdClass::class, array('__invoke')); - $next->expects($this->once())->method('__invoke')->with($envelope)->willReturn('Hello from $next'); + $next->expects($this->once())->method('__invoke')->with($envelope); $middleware = $this->createMock(MiddlewareInterface::class); $middleware->expects($this->never())->method('handle'); $decorator = new ActivationMiddlewareDecorator($middleware, false); - $this->assertSame('Hello from $next', $decorator->handle($envelope, $next)); + $decorator->handle($envelope, $next); } } diff --git a/src/Symfony/Component/Messenger/Tests/Middleware/Enhancers/TraceableMiddlewareTest.php b/src/Symfony/Component/Messenger/Tests/Middleware/Enhancers/TraceableMiddlewareTest.php index 88cf149670fc1..5e772a88fd809 100644 --- a/src/Symfony/Component/Messenger/Tests/Middleware/Enhancers/TraceableMiddlewareTest.php +++ b/src/Symfony/Component/Messenger/Tests/Middleware/Enhancers/TraceableMiddlewareTest.php @@ -33,7 +33,7 @@ public function testHandle() ->method('handle') ->with($message, $this->anything()) ->will($this->returnCallback(function ($message, callable $next) { - return $next($message); + $next($message); })) ; @@ -42,7 +42,6 @@ public function testHandle() ->expects($this->once()) ->method('__invoke') ->with($message) - ->willReturn($expectedReturnedValue = 'Hello') ; $stopwatch = $this->createMock(Stopwatch::class); @@ -58,7 +57,7 @@ public function testHandle() $traced = new TraceableMiddleware($middleware, $stopwatch, $busId); - $this->assertSame($expectedReturnedValue, $traced->handle($envelope, $next)); + $traced->handle($envelope, $next); } /** @@ -75,7 +74,7 @@ public function testHandleWithException() ->method('handle') ->with($message, $this->anything()) ->will($this->returnCallback(function ($message, callable $next) { - return $next($message); + $next($message); })) ; diff --git a/src/Symfony/Component/Messenger/Tests/Middleware/HandleMessageMiddlewareTest.php b/src/Symfony/Component/Messenger/Tests/Middleware/HandleMessageMiddlewareTest.php index 993a2de81265d..6791dd6477dc8 100644 --- a/src/Symfony/Component/Messenger/Tests/Middleware/HandleMessageMiddlewareTest.php +++ b/src/Symfony/Component/Messenger/Tests/Middleware/HandleMessageMiddlewareTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Messenger\Tests\Middleware; use PHPUnit\Framework\TestCase; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Handler\Locator\HandlerLocator; use Symfony\Component\Messenger\Middleware\HandleMessageMiddleware; use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage; @@ -21,9 +22,9 @@ class HandleMessageMiddlewareTest extends TestCase public function testItCallsTheHandlerAndNextMiddleware() { $message = new DummyMessage('Hey'); + $envelope = new Envelope($message); $handler = $this->createPartialMock(\stdClass::class, array('__invoke')); - $handler->method('__invoke')->willReturn('Hello'); $next = $this->createPartialMock(\stdClass::class, array('__invoke')); @@ -32,8 +33,8 @@ public function testItCallsTheHandlerAndNextMiddleware() ))); $handler->expects($this->once())->method('__invoke')->with($message); - $next->expects($this->once())->method('__invoke')->with($message); + $next->expects($this->once())->method('__invoke')->with($envelope); - $middleware->handle($message, $next); + $middleware->handle($envelope, $next); } } diff --git a/src/Symfony/Component/Messenger/Tests/Middleware/LoggingMiddlewareTest.php b/src/Symfony/Component/Messenger/Tests/Middleware/LoggingMiddlewareTest.php index e662a130fbba9..b3bbad8bdd781 100644 --- a/src/Symfony/Component/Messenger/Tests/Middleware/LoggingMiddlewareTest.php +++ b/src/Symfony/Component/Messenger/Tests/Middleware/LoggingMiddlewareTest.php @@ -32,12 +32,9 @@ public function testDebugLogAndNextMiddleware() ->expects($this->once()) ->method('__invoke') ->with($message) - ->willReturn('Hello') ; - $result = (new LoggingMiddleware($logger))->handle($message, $next); - - $this->assertSame('Hello', $result); + (new LoggingMiddleware($logger))->handle($message, $next); } /** diff --git a/src/Symfony/Component/Messenger/Tests/Middleware/ValidationMiddlewareTest.php b/src/Symfony/Component/Messenger/Tests/Middleware/ValidationMiddlewareTest.php index 23964c2e45e5a..a111c71886f00 100644 --- a/src/Symfony/Component/Messenger/Tests/Middleware/ValidationMiddlewareTest.php +++ b/src/Symfony/Component/Messenger/Tests/Middleware/ValidationMiddlewareTest.php @@ -38,12 +38,9 @@ public function testValidateAndNextMiddleware() ->expects($this->once()) ->method('__invoke') ->with($envelope) - ->willReturn('Hello') ; - $result = (new ValidationMiddleware($validator))->handle($envelope, $next); - - $this->assertSame('Hello', $result); + (new ValidationMiddleware($validator))->handle($envelope, $next); } public function testValidateWithConfigurationAndNextMiddleware() @@ -61,12 +58,9 @@ public function testValidateWithConfigurationAndNextMiddleware() ->expects($this->once()) ->method('__invoke') ->with($envelope) - ->willReturn('Hello') ; - $result = (new ValidationMiddleware($validator))->handle($envelope, $next); - - $this->assertSame('Hello', $result); + (new ValidationMiddleware($validator))->handle($envelope, $next); } /** diff --git a/src/Symfony/Component/Messenger/Tests/TraceableMessageBusTest.php b/src/Symfony/Component/Messenger/Tests/TraceableMessageBusTest.php index 339dc9ae5264d..03cdd14cd585a 100644 --- a/src/Symfony/Component/Messenger/Tests/TraceableMessageBusTest.php +++ b/src/Symfony/Component/Messenger/Tests/TraceableMessageBusTest.php @@ -20,21 +20,19 @@ class TraceableMessageBusTest extends TestCase { - public function testItTracesResult() + public function testItTracesDispatch() { $message = new DummyMessage('Hello'); $bus = $this->getMockBuilder(MessageBusInterface::class)->getMock(); - $bus->expects($this->once())->method('dispatch')->with($message)->willReturn($result = array('foo' => 'bar')); $traceableBus = new TraceableMessageBus($bus); $line = __LINE__ + 1; - $this->assertSame($result, $traceableBus->dispatch($message)); + $this->assertNull($traceableBus->dispatch($message)); $this->assertCount(1, $tracedMessages = $traceableBus->getDispatchedMessages()); $this->assertArraySubset(array( 'message' => $message, - 'result' => $result, - 'envelopeItems' => null, + 'envelopeItems' => array(), 'caller' => array( 'name' => 'TraceableMessageBusTest.php', 'file' => __FILE__, @@ -43,20 +41,18 @@ public function testItTracesResult() ), $tracedMessages[0], true); } - public function testItTracesResultWithEnvelope() + public function testItTracesDispatchWithEnvelope() { $envelope = Envelope::wrap($message = new DummyMessage('Hello'))->with($envelopeItem = new AnEnvelopeItem()); $bus = $this->getMockBuilder(MessageBusInterface::class)->getMock(); - $bus->expects($this->once())->method('dispatch')->with($envelope)->willReturn($result = array('foo' => 'bar')); $traceableBus = new TraceableMessageBus($bus); $line = __LINE__ + 1; - $this->assertSame($result, $traceableBus->dispatch($envelope)); + $this->assertNull($traceableBus->dispatch($envelope)); $this->assertCount(1, $tracedMessages = $traceableBus->getDispatchedMessages()); $this->assertArraySubset(array( 'message' => $message, - 'result' => $result, 'envelopeItems' => array($envelopeItem), 'caller' => array( 'name' => 'TraceableMessageBusTest.php', @@ -86,7 +82,7 @@ public function testItTracesExceptions() $this->assertArraySubset(array( 'message' => $message, 'exception' => $exception, - 'envelopeItems' => null, + 'envelopeItems' => array(), 'caller' => array( 'name' => 'TraceableMessageBusTest.php', 'file' => __FILE__, diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Enhancers/StopWhenTimeLimitIsReachedReceiverTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Enhancers/StopWhenTimeLimitIsReachedReceiverTest.php index 51119b36f56a1..295e9a48a1ee3 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Enhancers/StopWhenTimeLimitIsReachedReceiverTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Enhancers/StopWhenTimeLimitIsReachedReceiverTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Tests\Fixtures\CallbackReceiver; use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage; use Symfony\Component\Messenger\Transport\Enhancers\StopWhenTimeLimitIsReachedReceiver; @@ -25,7 +26,7 @@ class StopWhenTimeLimitIsReachedReceiverTest extends TestCase public function testReceiverStopsWhenTimeLimitIsReached() { $callable = function ($handler) { - $handler(new DummyMessage('API')); + $handler(new Envelope(new DummyMessage('API'))); }; $decoratedReceiver = $this->getMockBuilder(CallbackReceiver::class) diff --git a/src/Symfony/Component/Messenger/TraceableMessageBus.php b/src/Symfony/Component/Messenger/TraceableMessageBus.php index 2204f4e41ae2b..045d47e5ae789 100644 --- a/src/Symfony/Component/Messenger/TraceableMessageBus.php +++ b/src/Symfony/Component/Messenger/TraceableMessageBus.php @@ -27,35 +27,24 @@ public function __construct(MessageBusInterface $decoratedBus) /** * {@inheritdoc} */ - public function dispatch($message) + public function dispatch($message, string $name = null): void { - $caller = $this->getCaller(); - $callTime = microtime(true); - $messageToTrace = $message instanceof Envelope ? $message->getMessage() : $message; - $envelopeItems = $message instanceof Envelope ? array_values($message->all()) : null; + $envelope = Envelope::wrap($message, $name); + $context = array( + 'envelopeItems' => array_values($envelope->all()), + 'message' => $envelope->getMessage(), + 'caller' => $this->getCaller(), + 'callTime' => microtime(true), + ); try { - $result = $this->decoratedBus->dispatch($message); - - $this->dispatchedMessages[] = array( - 'envelopeItems' => $envelopeItems, - 'message' => $messageToTrace, - 'result' => $result, - 'callTime' => $callTime, - 'caller' => $caller, - ); - - return $result; + $this->decoratedBus->dispatch($envelope); } catch (\Throwable $e) { - $this->dispatchedMessages[] = array( - 'envelopeItems' => $envelopeItems, - 'message' => $messageToTrace, - 'exception' => $e, - 'callTime' => $callTime, - 'caller' => $caller, - ); + $context['exception'] = $e; throw $e; + } finally { + $this->dispatchedMessages[] = $context; } } @@ -85,10 +74,7 @@ private function getCaller(): array $line = $trace[$i]['line']; while (++$i < 8) { - if (isset($trace[$i]['function'], $trace[$i]['file']) && empty($trace[$i]['class']) && 0 !== strpos( - $trace[$i]['function'], - 'call_user_func' - )) { + if (isset($trace[$i]['function'], $trace[$i]['file']) && empty($trace[$i]['class']) && 0 !== strpos($trace[$i]['function'], 'call_user_func')) { $file = $trace[$i]['file']; $line = $trace[$i]['line']; diff --git a/src/Symfony/Component/Messenger/Transport/AmqpExt/AmqpSender.php b/src/Symfony/Component/Messenger/Transport/AmqpExt/AmqpSender.php index bb084a8f03ae7..b66af383e5b06 100644 --- a/src/Symfony/Component/Messenger/Transport/AmqpExt/AmqpSender.php +++ b/src/Symfony/Component/Messenger/Transport/AmqpExt/AmqpSender.php @@ -35,7 +35,7 @@ public function __construct(Connection $connection, SerializerInterface $seriali /** * {@inheritdoc} */ - public function send(Envelope $envelope) + public function send(Envelope $envelope): void { $encodedMessage = $this->serializer->encode($envelope); diff --git a/src/Symfony/Component/Messenger/Transport/Enhancers/StopWhenTimeLimitIsReachedReceiver.php b/src/Symfony/Component/Messenger/Transport/Enhancers/StopWhenTimeLimitIsReachedReceiver.php index b88a0cbd046c9..1ede7b2a31412 100644 --- a/src/Symfony/Component/Messenger/Transport/Enhancers/StopWhenTimeLimitIsReachedReceiver.php +++ b/src/Symfony/Component/Messenger/Transport/Enhancers/StopWhenTimeLimitIsReachedReceiver.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Messenger\Transport\Enhancers; use Psr\Log\LoggerInterface; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Transport\ReceiverInterface; /** @@ -32,13 +33,13 @@ public function __construct(ReceiverInterface $decoratedReceiver, int $timeLimit public function receive(callable $handler): void { - $startTime = time(); + $startTime = microtime(true); $endTime = $startTime + $this->timeLimitInSeconds; - $this->decoratedReceiver->receive(function ($message) use ($handler, $endTime) { - $handler($message); + $this->decoratedReceiver->receive(function (?Envelope $envelope) use ($handler, $endTime) { + $handler($envelope); - if ($endTime < time()) { + if ($endTime < microtime(true)) { $this->stop(); if (null !== $this->logger) { $this->logger->info('Receiver stopped due to time limit of {timeLimit}s reached', array('timeLimit' => $this->timeLimitInSeconds)); diff --git a/src/Symfony/Component/Messenger/Transport/SenderInterface.php b/src/Symfony/Component/Messenger/Transport/SenderInterface.php index a400420ac0641..0e0e62ec6ba6f 100644 --- a/src/Symfony/Component/Messenger/Transport/SenderInterface.php +++ b/src/Symfony/Component/Messenger/Transport/SenderInterface.php @@ -20,8 +20,6 @@ interface SenderInterface { /** * Sends the given envelope. - * - * @param Envelope $envelope */ - public function send(Envelope $envelope); + public function send(Envelope $envelope): void; }