8000 feature #30676 Avoid dispatching SendMessageToTransportsEvent on rede… · symfony/symfony@0034a0f · GitHub
[go: up one dir, main page]

Skip to content

Commit 0034a0f

Browse files
committed
feature #30676 Avoid dispatching SendMessageToTransportsEvent on redeliver (weaverryan)
This PR was merged into the 4.3-dev branch. Discussion ---------- Avoid dispatching SendMessageToTransportsEvent on redeliver | Q | A | ------------- | --- | Branch? | master | Bug fix? | yes - I think so | New feature? | no | BC breaks? | no (feature only on master) | Deprecations? | no | Tests pass? | yes | Fixed tickets | none | License | MIT | Doc PR | a lot, soon :) This purpose of this event is to be a hook when a message is sent to a transport. If that message is redelivered later, that's not the purpose of this hook (there are Worker events for that) and could cause problems if the user unknowingly tries to modify the Envelope in some way, not thinking about how this might be a redelivery message. Commits ------- 3ac6bf9 Avoid dispatching SendMessageToTransportsEvent on redeliver
2 parents 40e9a77 + 3ac6bf9 commit 0034a0f

File tree

3 files changed

+40
-10
lines changed

3 files changed

+40
-10
lines changed

src/Symfony/Component/Messenger/Event/SendMessageToTransportsEvent.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
* The event is *only* dispatched if the message will actually
2121
* be sent to at least one transport. If the message is sent
2222
* to multiple transports, the message is dispatched only one time.
23+
* This message is only dispatched the first time a message
24+
* is sent to a transport, not also if it is retried.
2325
*
2426
* @author Ryan Weaver <ryan@symfonycasts.com>
2527
*/

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,21 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope
6262
/** @var RedeliveryStamp|null $redeliveryStamp */
6363
$redeliveryStamp = $envelope->last(RedeliveryStamp::class);
6464

65-
$senders = \iterator_to_array($this->sendersLocator->getSenders($envelope, $handle));
66-
67-
if (null !== $this->eventDispatcher && \count($senders) > 0) {
68-
$event = new SendMessageToTransportsEvent($envelope);
69-
$this->eventDispatcher->dispatch($event);
70-
$envelope = $event->getEnvelope();
71-
}
72-
73-
foreach ($senders as $alias => $sender) {
65+
// dispatch event unless this is a redelivery
66+
$shouldDispatchEvent = null === $redeliveryStamp;
67+
foreach ($this->sendersLocator->getSenders($envelope, $handle) as $alias => $sender) {
7468
// on redelivery, only deliver to the given sender
7569
if (null !== $redeliveryStamp && !$redeliveryStamp->shouldRedeliverToSender(\get_class($sender), $alias)) {
7670
continue;
7771
}
7872

73+
if (null !== $this->eventDispatcher && $shouldDispatchEvent) {
74+
$event = new SendMessageToTransportsEvent($envelope);
75+
$this->eventDispatcher->dispatch($event);
76+
$envelope = $event->getEnvelope();
77+
$shouldDispatchEvent = false;
78+
}
79+
7980
$this->logger->info('Sending message "{class}" with "{sender}"', $context + ['sender' => \get_class($sender)]);
8081
$envelope = $sender->send($envelope->with(new SentStamp(\get_class($sender), \is_string($alias) ? $alias : null)));
8182
}

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ public function testItSkipsReceivedMessages()
205205
$this->assertNull($envelope->last(SentStamp::class), 'it does not add sent stamp for received messages');
206206
}
207207

208-
public function testItDispatchesTheEventOnceTime()
208+
public function testItDispatchesTheEventOneTime()
209209
{
210210
$envelope = new Envelope(new DummyMessage('original envelope'));
211211

@@ -224,4 +224,31 @@ public function testItDispatchesTheEventOnceTime()
224224

225225
$middleware->handle($envelope, $this->getStackMock(false));
226226
}
227+
228+
public function testItDoesNotDispatchWithNoSenders()
229+
{
230+
$envelope = new Envelope(new DummyMessage('original envelope'));
231+
232+
$dispatcher = $this->createMock(EventDispatcherInterface::class);
233+
$dispatcher->expects($this->never())->method('dispatch');
234+
235+
$middleware = new SendMessageMiddleware(new SendersLocator([]), $dispatcher);
236+
237+
$middleware->handle($envelope, $this->getStackMock());
238+
}
239+
240+
public function testItDoesNotDispatchOnRetry()
241+
{
242+
$envelope = new Envelope(new DummyMessage('original envelope'));
243+
$envelope = $envelope->with(new RedeliveryStamp(3, 'foo_sender'));
244+
245+
$dispatcher = $this->createMock(EventDispatcherInterface::class);
246+
$dispatcher->expects($this->never())->method('dispatch');
247+
248+
$sender = $this->getMockBuilder(SenderInterface::class)->getMock();
249+
250+
$middleware = new SendMessageMiddleware(new SendersLocator([DummyMessage::class => [$sender]]), $dispatcher);
251+
252+
$middleware->handle($envelope, $this->getStackMock(false));
253+
}
227254
}

0 commit comments

Comments
 (0)
0