11
11
12
12
namespace Symfony \Component \Messenger ;
13
13
14
- use Symfony \Component \Messenger \Exception \InvalidArgumentException ;
15
14
use Symfony \Component \Messenger \Middleware \MiddlewareInterface ;
16
15
17
16
/**
18
17
* @author Samuel Roze <samuel.roze@gmail.com>
19
18
* @author Matthias Noback <matthiasnoback@gmail.com>
19
+ * @author Nicolas Grekas <p@tchwork.com>
20
20
*/
21
21
class MessageBus implements MessageBusInterface
22
22
{
23
- private $ middlewareHandlers ;
24
-
25
- /**
26
- * @var MiddlewareInterface[]|null
27
- */
28
- private $ indexedMiddlewareHandlers ;
23
+ private $ middlewareAggregate ;
29
24
30
25
/**
31
26
* @param MiddlewareInterface[]|iterable $middlewareHandlers
32
27
*/
33
28
public function __construct (iterable $ middlewareHandlers = array ())
34
29
{
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 class () {
36
+ public $ aggregate ;
37
+ public $ iterator ;
38
+
39
+ public function getIterator ()
40
+ {
41
+ return $ this ->aggregate = new \ArrayObject (iterator_to_array ($ this ->iterator , false ));
42
+ }
43
+ };
44
+ $ this ->middlewareAggregate ->aggregate = &$ this ->middlewareAggregate ;
45
+ $ this ->middlewareAggregate ->iterator = $ middlewareHandlers ;
46
+ }
36
47
}
37
48
38
49
/**
@@ -41,37 +52,45 @@ public function __construct(iterable $middlewareHandlers = array())
41
52
public function dispatch ($ message ): void
42
53
{
43
54
if (!\is_object ($ message )) {
44
- throw new InvalidArgumentException (sprintf ('Invalid type for message argument. Expected object, but got "%s". ' , \gettype ($ message )));
55
+ throw new \ TypeError (sprintf ('Invalid argument provided to "%s()": expected object, but got %s. ' , __METHOD__ , \gettype ($ message )));
45
56
}
46
57
47
- \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 );
58
+ $ middlewareIterator = $ this ->middlewareAggregate ->getIterator ();
59
+ while ($ middlewareIterator instanceof \IteratorAggregate) {
60
+ $ middlewareIterator = $ middlewareIterator ->getIterator ();
54
61
}
55
62
56
- if (!isset ($ this ->indexedMiddlewareHandlers [$ index ])) {
57
- return function () {};
58
- }
63
+ foreach ($ middlewareIterator as $ middleware ) {
64
+ $ currentEnvelope = $ message instanceof Envelope ? $ message : new Envelope ($ message );
65
+
66
+ // Do not provide the envelope if the middleware cannot read it:
67
+ $ message = $ middleware instanceof EnvelopeAwareInterface ? $ currentEnvelope : $ currentEnvelope ->getMessage ();
68
+
69
+ $ next = static function ($ message ) use ($ middlewareIterator , &$ currentEnvelope , &$ next ) {
70
+ $ middlewareIterator ->next ();
71
+
72
+ if (!$ middlewareIterator ->valid ()) {
73
+ return ;
74
+ }
59
75
60
- $ middleware = $ this -> indexedMiddlewareHandlers [ $ index ] ;
76
+ $ middleware = $ middlewareIterator -> current () ;
61
77
62
- return function ($ message ) use ($ middleware , $ index , $ currentEnvelope ) {
63
- if ($ message instanceof Envelope) {
64
- $ currentEnvelope = $ message ;
65
- } else {
66
- $ message = $ currentEnvelope ->withMessage ($ message );
67
- }
78
+ if ($ message instanceof Envelope) {
79
+ $ currentEnvelope = $ message ;
80
+ } else {
81
+ $ message = $ currentEnvelope ->withMessage ($ message );
82
+ }
68
83
69
- if (!$ middleware instanceof EnvelopeAwareInterface) {
70
- // Do not provide the envelope if the middleware cannot read it:
71
- $ message = $ message ->getMessage ();
72
- }
84
+ if (!$ middleware instanceof EnvelopeAwareInterface) {
85
+ $ message = $ message ->getMessage ();
86
+ }
73
87
74
- $ middleware ->handle ($ message , $ this ->callableForNextMiddleware ($ index + 1 , $ currentEnvelope ));
75
- };
88
+ $ middleware ->handle ($ message , $ next );
89
+ };
90
+
91
+ $ middleware ->handle ($ message , $ next );
92
+
93
+ break ;
94
+ }
76
95
}
77
96
}
0 commit comments