Skip to content

Commit aa56d07

Browse files
bug #51675 [Messenger] Fix cloned TraceableStack not unstacking the stack independently (krciga22)
This PR was squashed before being merged into the 5.4 branch. Discussion ---------- [Messenger] Fix cloned TraceableStack not unstacking the stack independently | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #51564 | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> Fixed a bug with cloned `TraceableStack` not unstacking the stack independently from the original due to the __clone() method not yet being implemented. Clones of `StackMiddleware` currently unstack the stack independently, but not `TraceableStack`. Commits ------- b91bdc6 [Messenger] Fix cloned TraceableStack not unstacking the stack independently
2 parents b9c30fb + b91bdc6 commit aa56d07

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

src/Symfony/Component/Messenger/Middleware/TraceableMiddleware.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,9 @@ public function stop(): void
9494
}
9595
$this->currentEvent = null;
9696
}
97+
98+
public function __clone()
99+
{
100+
$this->stack = clone $this->stack;
101+
}
97102
}

src/Symfony/Component/Messenger/Tests/Middleware/TraceableMiddlewareTest.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\Messenger\Middleware\StackInterface;
1717
use Symfony\Component\Messenger\Middleware\StackMiddleware;
1818
use Symfony\Component\Messenger\Middleware\TraceableMiddleware;
19+
use Symfony\Component\Messenger\Middleware\TraceableStack;
1920
use Symfony\Component\Messenger\Test\Middleware\MiddlewareTestCase;
2021
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
2122
use Symfony\Component\Stopwatch\Stopwatch;
@@ -140,4 +141,92 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope
140141
$traced->handle($envelope, new StackMiddleware(new \ArrayIterator([null, $middleware])));
141142
$this->assertSame(1, $middleware->calls);
142143
}
144+
145+
public function testClonedTraceableStackUnstacksIndependently()
146+
{
147+
// import TraceableStack
148+
class_exists(TraceableMiddleware::class);
149+
150+
$stackMiddleware = new StackMiddleware([
151+
null,
152+
$this->createMock(MiddlewareInterface::class),
153+
$this->createMock(MiddlewareInterface::class),
154+
]);
155+
156+
$stopwatch = $this->createMock(Stopwatch::class);
157+
158+
$traceableStack = new TraceableStack($stackMiddleware, $stopwatch, 'command_bus', 'messenger.middleware');
159+
$clonedStack = clone $traceableStack;
160+
161+
$traceableStackMiddleware1 = $traceableStack->next();
162+
$traceableStackMiddleware2 = $traceableStack->next();
163+
$traceableStackTail = $traceableStack->next();
164+
self::assertSame($stackMiddleware, $traceableStackTail);
165+
166+
// unstack clonedStack independently
167+
$clonedStackMiddleware1 = $clonedStack->next();
168+
self::assertSame($traceableStackMiddleware1, $clonedStackMiddleware1);
169+
self::assertNotSame($traceableStackMiddleware2, $clonedStackMiddleware1);
170+
171+
$clonedStackMiddleware2 = $clonedStack->next();
172+
self::assertSame($traceableStackMiddleware2, $clonedStackMiddleware2);
173+
174+
$clonedStackTail = $clonedStack->next();
175+
self::assertNotSame($stackMiddleware, $clonedStackTail, 'stackMiddleware was also cloned');
176+
}
177+
178+
public function testClonedTraceableStackUsesSameStopwatch()
179+
{
180+
// import TraceableStack
181+
class_exists(TraceableMiddleware::class);
182+
183+
$middlewareIterable = [null, $this->createMock(MiddlewareInterface::class)];
184+
185+
$stackMiddleware = new StackMiddleware($middlewareIterable);
186+
187+
$stopwatch = $this->createMock(Stopwatch::class);
188+
$stopwatch->expects($this->exactly(2))->method('isStarted')->willReturn(true);
189+
190+
$startSeries = [
191+
[$this->matches('"%sMiddlewareInterface%s" on "command_bus"'), 'messenger.middleware'],
192+
[$this->identicalTo('Tail on "command_bus"'), 'messenger.middleware'],
193+
[$this->matches('"%sMiddlewareInterface%s" on "command_bus"'), 'messenger.middleware'],
194+
[$this->identicalTo('Tail on "command_bus"'), 'messenger.middleware'],
195+
];
196+
$stopwatch->expects($this->exactly(4))
197+
->method('start')
198+
->willReturnCallback(function (string $name, string $category = null) use (&$startSeries) {
199+
[$constraint, $expectedCategory] = array_shift($startSeries);
200+
201+
$constraint->evaluate($name);
202+
$this->assertSame($expectedCategory, $category);
203+
204+
return $this->createMock(StopwatchEvent::class);
205+
})
206+
;
207+
208+
$stopSeries = [
209+
$this->matches('"%sMiddlewareInterface%s" on "command_bus"'),
210+
$this->matches('"%sMiddlewareInterface%s" on "command_bus"'),
211+
];
212+
$stopwatch->expects($this->exactly(2))
213+
->method('stop')
214+
->willReturnCallback(function (string $name) use (&$stopSeries) {
215+
$constraint = array_shift($stopSeries);
216+
$constraint->evaluate($name);
217+
218+
return $this->createMock(StopwatchEvent::class);
219+
})
220+
;
221+
222+
$traceableStack = new TraceableStack($stackMiddleware, $stopwatch, 'command_bus', 'messenger.middleware');
223+
$clonedStack = clone $traceableStack;
224+
225+
// unstack the stacks independently
226+
$traceableStack->next();
227+
$traceableStack->next();
228+
229+
$clonedStack->next();
230+
$clonedStack->next();
231+
}
143232
}

0 commit comments

Comments
 (0)
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