From 6a5d7a1aace0b898affde1cab4ea51ad8c5ec29d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 17 Oct 2018 15:58:28 +0200 Subject: [PATCH] [Messenger] make middlewares truly lazy on a bus --- .../Component/Messenger/MessageBus.php | 53 ++++++++++++------- .../DependencyInjection/MessengerPassTest.php | 12 ++--- .../Messenger/Tests/MessageBusTest.php | 4 +- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/Symfony/Component/Messenger/MessageBus.php b/src/Symfony/Component/Messenger/MessageBus.php index ecaa0623fe0b7..96fa689968543 100644 --- a/src/Symfony/Component/Messenger/MessageBus.php +++ b/src/Symfony/Component/Messenger/MessageBus.php @@ -11,28 +11,39 @@ 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 class() { + public $aggregate; + public $iterator; + + public function getIterator() + { + return $this->aggregate = new \ArrayObject(iterator_to_array($this->iterator, false)); + } + }; + $this->middlewareAggregate->aggregate = &$this->middlewareAggregate; + $this->middlewareAggregate->iterator = $middlewareHandlers; + } } /** @@ -41,24 +52,26 @@ public function __construct(iterable $middlewareHandlers = array()) public function dispatch($message): void { if (!\is_object($message)) { - throw new InvalidArgumentException(sprintf('Invalid type for message argument. Expected object, but got "%s".', \gettype($message))); + throw new \TypeError(sprintf('Invalid argument provided to "%s()": expected object, but got %s.', __METHOD__, \gettype($message))); } + $middlewareIterator = $this->middlewareAggregate->getIterator(); - $this->callableForNextMiddleware(0)($message instanceof Envelope ? $message : new Envelope($message)); - } - - private function callableForNextMiddleware(int $index): callable - { - if (null === $this->indexedMiddlewareHandlers) { - $this->indexedMiddlewareHandlers = \is_array($this->middlewareHandlers) ? array_values($this->middlewareHandlers) : iterator_to_array($this->middlewareHandlers, false); + while ($middlewareIterator instanceof \IteratorAggregate) { + $middlewareIterator = $middlewareIterator->getIterator(); } + $middlewareIterator->rewind(); - if (!isset($this->indexedMiddlewareHandlers[$index])) { - return static function () {}; + if (!$middlewareIterator->valid()) { + return; } + $next = static function (Envelope $envelope) use ($middlewareIterator, &$next) { + $middlewareIterator->next(); - return function (Envelope $envelope) use ($index) { - $this->indexedMiddlewareHandlers[$index]->handle($envelope, $this->callableForNextMiddleware($index + 1)); + if ($middlewareIterator->valid()) { + $middlewareIterator->current()->handle($envelope, $next); + } }; + + $middlewareIterator->current()->handle($message instanceof Envelope ? $message : new Envelope($message), $next); } } diff --git a/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php b/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php index 85db4cb195206..28530d7ea0daa 100644 --- a/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php +++ b/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php @@ -90,10 +90,10 @@ public function testProcessHandlersByBus() ->setAbstract(true) ; - $middlewares = array(array('id' => 'call_message_handler')); + $middlewareHandlers = array(array('id' => 'call_message_handler')); - $container->setParameter($commandBusId.'.middleware', $middlewares); - $container->setParameter($queryBusId.'.middleware', $middlewares); + $container->setParameter($commandBusId.'.middleware', $middlewareHandlers); + $container->setParameter($queryBusId.'.middleware', $middlewareHandlers); $container->register(DummyCommandHandler::class)->addTag('messenger.message_handler', array('bus' => $commandBusId)); $container->register(DummyQueryHandler::class)->addTag('messenger.message_handler', array('bus' => $queryBusId)); @@ -607,10 +607,10 @@ public function testItRegistersTheDebugCommand() $container->register('console.command.messenger_debug', DebugCommand::class)->addArgument(array()); - $middlewares = array(array('id' => 'call_message_handler')); + $middlewareHandlers = array(array('id' => 'call_message_handler')); - $container->setParameter($commandBusId.'.middleware', $middlewares); - $container->setParameter($queryBusId.'.middleware', $middlewares); + $container->setParameter($commandBusId.'.middleware', $middlewareHandlers); + $container->setParameter($queryBusId.'.middleware', $middlewareHandlers); $container->register(DummyCommandHandler::class)->addTag('messenger.message_handler', array('bus' => $commandBusId)); $container->register(DummyQueryHandler::class)->addTag('messenger.message_handler', array('bus' => $queryBusId)); diff --git a/src/Symfony/Component/Messenger/Tests/MessageBusTest.php b/src/Symfony/Component/Messenger/Tests/MessageBusTest.php index 0ea4c644ce66d..c89eab3586300 100644 --- a/src/Symfony/Component/Messenger/Tests/MessageBusTest.php +++ b/src/Symfony/Component/Messenger/Tests/MessageBusTest.php @@ -30,8 +30,8 @@ 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() { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy