Skip to content

Commit

Permalink
bug #54057 [Messenger] Passing actual Envelope to `WorkerMessageRet…
Browse files Browse the repository at this point in the history
…riedEvent` (daffoxdev)

This PR was merged into the 5.4 branch.

Discussion
----------

[Messenger] Passing actual `Envelope` to `WorkerMessageRetriedEvent`

| Q             | A
| ------------- | ---
| Branch?       |5.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #52914
| License       | MIT

In `SendFailedMessageForRetryListener` fixed the `Envelope` instance that passes to `WorkerMessageRetriedEvent`. Now it is instance of `Envelope` the that is returned by transport sender and could include such stamps as `TransportMessageIdStamp`. Previously to the event passed the not actual envelope that is created before passed to `send()`

- changes in SendFailedMessageForRetryListener
- added new test for this case in `SendFailedMessageForRetryListenerTest`

Commits
-------

9b4cc57f28 [Messenger] Passing to `WorkerMessageRetriedEvent` envelope with actual stamps after sent
  • Loading branch information
fabpot committed Jul 5, 2024
2 parents cd90fa1 + ab320a2 commit d21b1d0
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
2 changes: 1 addition & 1 deletion EventListener/SendFailedMessageForRetryListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function onMessageFailed(WorkerMessageFailedEvent $event)
$retryEnvelope = $this->withLimitedHistory($envelope, new DelayStamp($delay), new RedeliveryStamp($retryCount));

// re-send the message for retry
$this->getSenderForTransport($event->getReceiverName())->send($retryEnvelope);
$retryEnvelope = $this->getSenderForTransport($event->getReceiverName())->send($retryEnvelope);

if (null !== $this->eventDispatcher) {
$this->eventDispatcher->dispatch(new WorkerMessageRetriedEvent($retryEnvelope, $event->getReceiverName()));
Expand Down
46 changes: 46 additions & 0 deletions Tests/EventListener/SendFailedMessageForRetryListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@

use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\Event\WorkerMessageRetriedEvent;
use Symfony\Component\Messenger\EventListener\SendFailedMessageForRetryListener;
use Symfony\Component\Messenger\Exception\RecoverableMessageHandlingException;
use Symfony\Component\Messenger\Retry\RetryStrategyInterface;
use Symfony\Component\Messenger\Stamp\DelayStamp;
use Symfony\Component\Messenger\Stamp\RedeliveryStamp;
use Symfony\Component\Messenger\Stamp\TransportMessageIdStamp;
use Symfony\Component\Messenger\Transport\Sender\SenderInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

Expand Down Expand Up @@ -190,4 +193,47 @@ public function testEnvelopeKeepOnlyTheLast10Stamps()

$listener->onMessageFailed($event);
}

public function testRetriedEnvelopePassesToRetriedEvent()
{
$exception = new \Exception('no!');
$envelope = new Envelope(new \stdClass());

$sender = $this->createMock(SenderInterface::class);
$sender->expects($this->once())->method('send')->willReturnCallback(static function (Envelope $envelope) {
return $envelope->with(new TransportMessageIdStamp(123));
});

$eventDispatcher = $this->createMock(EventDispatcherInterface::class);
$eventDispatcher->expects($this->once())->method('dispatch')->willReturnCallback(
function (WorkerMessageRetriedEvent $retriedEvent) {
$envelope = $retriedEvent->getEnvelope();

$transportIdStamp = $envelope->last(TransportMessageIdStamp::class);
$this->assertNotNull($transportIdStamp);

return $retriedEvent;
});

$senderLocator = new Container();
$senderLocator->set('my_receiver', $sender);

$retryStrategy = $this->createMock(RetryStrategyInterface::class);
$retryStrategy->expects($this->once())->method('isRetryable')->willReturn(true);
$retryStrategy->expects($this->once())->method('getWaitingTime')->willReturn(1000);

$retryStrategyLocator = new Container();
$retryStrategyLocator->set('my_receiver', $retryStrategy);

$listener = new SendFailedMessageForRetryListener(
$senderLocator,
$retryStrategyLocator,
null,
$eventDispatcher
);

$event = new WorkerMessageFailedEvent($envelope, 'my_receiver', $exception);

$listener->onMessageFailed($event);
}
}

0 comments on commit d21b1d0

Please sign in to comment.