8000 [Messenger] make middlewares truly lazy on a bus · symfony/symfony@fe04974 · GitHub
[go: up one dir, main page]

Skip to content

Commit fe04974

Browse files
[Messenger] make middlewares truly lazy on a bus
1 parent dd432c4 commit fe04974

File tree

2 files changed

+41
-34
lines changed

2 files changed

+41
-34
lines changed

src/Symfony/Component/Messenger/MessageBus.php

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,29 @@
1111

1212
namespace Symfony\Component\Messenger;
1313

14-
use Symfony\Component\Messenger\Exception\InvalidArgumentException;
1514
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
1615

1716
/**
1817
* @author Samuel Roze <samuel.roze@gmail.com>
1918
* @author Matthias Noback <matthiasnoback@gmail.com>
19+
* @author Nicolas Grekas <p@tchwork.com>
2020
*/
2121
class MessageBus implements MessageBusInterface
2222
{
23-
private $middlewareHandlers;
24-
25-
/**
26-
* @var MiddlewareInterface[]|null
27-
*/
28-
private $indexedMiddlewareHandlers;
23+
private $middlewareAggregate;
2924

3025
/**
3126
* @param MiddlewareInterface[]|iterable $middlewareHandlers
3227
*/
3328
public function __construct(iterable $middlewareHandlers = array())
3429
{
35-
$this->middlewareHandlers = $middlewareHandlers;
30+
if ($middlewareHandlers instanceof \IteratorAggregate) {
31+
$this->middlewareAggregate = $middlewareHandlers;
32+
} elseif (\is_array($middlewareHandlers)) {
33+
$this->middlewareAggregate = new \ArrayObject($middlewareHandlers);
34+
} else {
35+
$this->middlewareAggregate = new \ArrayObject(iterator_to_array($middlewareHandlers, false));
36+
}
3637
}
3738

3839
/**
@@ -41,37 +42,43 @@ public function __construct(iterable $middlewareHandlers = array())
4142
public function dispatch($message)
4243
{
4344
if (!\is_object($message)) {
44-
throw new InvalidArgumentException(sprintf('Invalid type for message argument. Expected object, but got "%s".', \gettype($message)));
45+
throw new \TypeError(sprintf('Invalid argument provided to "%s()": expected object, but got %s.', __METHOD__, \gettype($message)));
4546
}
4647

47-
return \call_user_func($this->callableForNextMiddleware(0, Envelope::wrap($message)), $message);
48-
}
49-
50-
private function callableForNextMiddleware(int $index, Envelope $currentEnvelope): callable
51-
{
52-
if (null === $this->indexedMiddlewareHandlers) {
53-
$this->indexedMiddlewareHandlers = \is_array($this->middlewareHandlers) ? array_values($this->middlewareHandlers) : iterator_to_array($this->middlewareHandlers, false);
48+
$middlewareIterator = $this->middlewareAggregate->getIterator();
49+
while (!$middlewareIterator instanceof \Iterator) {
50+
$middlewareIterator = $middlewareIterator->getIterator();
5451
}
5552

56-
if (!isset($this->indexedMiddlewareHandlers[$index])) {
57-
return function () {};
58-
}
53+
foreach ($middlewareIterator as $middleware) {
54+
$currentEnvelope = Envelope::wrap($message);
55+
56+
// Do not provide the envelope if the middleware cannot read it:
57+
$message = $middleware instanceof EnvelopeAwareInterface ? $currentEnvelope : $currentEnvelope->getMessage();
58+
59+
$next = static function ($message) use ($middlewareIterator, &$currentEnvelope, &$next) {
60+
$middlewareIterator->next();
5961

60-
$middleware = $this->indexedMiddlewareHandlers[$index];
62+
if (!$middlewareIterator->valid()) {
63+
return;
64+
}
6165

62-
return function ($message) use ($middleware, $index, $currentEnvelope) {
63-
if ($message instanceof Envelope) {
64-
$currentEnvelope = $message;
65-
} else {
66-
$message = $currentEnvelope->withMessage($message);
67-
}
66+
$middleware = $middlewareIterator->current();
6867

69-
if (!$middleware instanceof EnvelopeAwareInterface) {
70-
// Do not provide the envelope if the middleware cannot read it:
71-
$message = $message->getMessage();
72-
}
68+
if ($message instanceof Envelope) {
69+
$currentEnvelope = $message;
70+
} else {
71+
$message = $currentEnvelope->withMessage($message);
72+
}
7373

74-
return $middleware->handle($message, $this->callableForNextMiddleware($index + 1, $currentEnvelope));
75-
};
74+
if (!$middleware instanceof EnvelopeAwareInterface) {
75+
$message = $message->getMessage();
76+
}
77+
78+
return $middleware->handle($message, $next);
79+
};
80+
81+
return $middleware->handle($message, $next);
82+
}
7683
}
7784
}

src/Symfony/Component/Messenger/Tests/MessageBusTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ public function testItHasTheRightInterface()
3131
}
3232

3333
/**
34-
* @expectedException \Symfony\Component\Messenger\Exception\InvalidArgumentException
35-
* @expectedExceptionMessage Invalid type for message argument. Expected object, but got "string".
34+
* @expectedException \TypeError
35+
* @expectedExceptionMessage Invalid argument provided to "Symfony\Component\Messenger\MessageBus::dispatch()": expected object, but got string.
3636
*/
3737
public function testItDispatchInvalidMessageType()
3838
{

0 commit comments

Comments
 (0)
0