1717
1818use Drift \CommandBus \Exception \InvalidCommandException ;
1919use Drift \CommandBus \Middleware \DebugableMiddleware ;
20- use Drift \CommandBus \Middleware \Middleware ;
20+ use React \EventLoop \LoopInterface ;
21+ use React \Promise \Deferred ;
2122
2223/**
2324 * Interface Bus.
2425 */
2526abstract class Bus
2627{
28+ /**
29+ * @var string
30+ */
31+ const DISTRIBUTION_INLINE = 'inline ' ;
32+
33+ /**
34+ * @var string
35+ */
36+ const DISTRIBUTION_NEXT_TICK = 'next_tick ' ;
37+
2738 /**
2839 * @var callable
2940 */
3041 private $ middlewareChain ;
3142
43+ /**
44+ * @var LoopInterface
45+ */
46+ private $ loop ;
47+
3248 /**
3349 * @var array
3450 */
3551 private $ middleware ;
3652
3753 /**
38- * @param array $middleware
54+ * @param LoopInterface $loop
55+ * @param array $middleware
56+ * @param string $distribution
3957 */
40- public function __construct (array $ middleware )
41- {
58+ public function __construct (
59+ LoopInterface $ loop ,
60+ array $ middleware ,
61+ string $ distribution
62+ ) {
63+ $ this ->loop = $ loop ;
4264 $ this ->middleware = array_map (function (DebugableMiddleware $ middleware ) {
4365 return $ middleware ->getMiddlewareInfo ();
4466 }, $ middleware );
45- $ this ->middlewareChain = $ this ->createExecutionChain ($ middleware );
67+
68+ $ this ->middlewareChain = self ::DISTRIBUTION_NEXT_TICK === $ distribution
69+ ? $ this ->createNextTickExecutionChain ($ middleware )
70+ : $ this ->createInlineExecutionChain ($ middleware );
4671 }
4772
4873 /**
@@ -64,13 +89,13 @@ protected function handle($command)
6489 }
6590
6691 /**
67- * Create execution chain.
92+ * Create inline execution chain.
6893 *
6994 * @param array $middlewareList
7095 *
7196 * @return callable
7297 */
73- private function createExecutionChain ($ middlewareList )
98+ private function createInlineExecutionChain ($ middlewareList )
7499 {
75100 $ lastCallable = function () {};
76101
@@ -83,6 +108,36 @@ private function createExecutionChain($middlewareList)
83108 return $ lastCallable ;
84109 }
85110
111+ /**
112+ * Create next tick execution chain.
113+ *
114+ * @param array $middlewareList
115+ *
116+ * @return callable
117+ */
118+ private function createNextTickExecutionChain ($ middlewareList )
119+ {
120+ $ lastCallable = function () {};
121+
122+ while ($ middleware = array_pop ($ middlewareList )) {
123+ $ lastCallable = function ($ command ) use ($ middleware , $ lastCallable ) {
124+ $ deferred = new Deferred ();
125+ $ this
126+ ->loop
127+ ->futureTick (function () use ($ deferred , $ middleware , $ command , $ lastCallable ) {
128+ $ deferred ->resolve ($ middleware ->execute (
129+ $ command ,
130+ $ lastCallable
131+ ));
132+ });
133+
134+ return $ deferred ->promise ();
135+ };
136+ }
137+
138+ return $ lastCallable ;
139+ }
140+
86141 /**
87142 * Get middleware list.
88143 *
0 commit comments