Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5fa9d68

Browse filesBrowse files
Benjamin Dos Santosfabpot
Benjamin Dos Santos
authored andcommitted
[Messenger] Add a \Throwable argument in RetryStrategyInterface methods
1 parent 0bec08f commit 5fa9d68
Copy full SHA for 5fa9d68

File tree

7 files changed

+61
-6
lines changed
Filter options

7 files changed

+61
-6
lines changed

‎UPGRADE-5.1.md

Copy file name to clipboardExpand all lines: UPGRADE-5.1.md
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ Messenger
7373
* Deprecated Doctrine transport. It has moved to a separate package. Run `composer require symfony/doctrine-messenger` to use the new classes.
7474
* Deprecated RedisExt transport. It has moved to a separate package. Run `composer require symfony/redis-messenger` to use the new classes.
7575
* Deprecated use of invalid options in Redis and AMQP connections.
76+
* Deprecated *not* declaring a `\Throwable` argument in `RetryStrategyInterface::isRetryable()`
77+
* Deprecated *not* declaring a `\Throwable` argument in `RetryStrategyInterface::getWaitingTime()`
7678

7779
Notifier
7880
--------

‎UPGRADE-6.0.md

Copy file name to clipboardExpand all lines: UPGRADE-6.0.md
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ Messenger
6565
* Removed Doctrine transport. Run `composer require symfony/doctrine-messenger` to keep the transport in your application.
6666
* Removed RedisExt transport. Run `composer require symfony/redis-messenger` to keep the transport in your application.
6767
* Use of invalid options in Redis and AMQP connections now throws an error.
68+
* The signature of method `RetryStrategyInterface::isRetryable()` has been updated to `RetryStrategyInterface::isRetryable(Envelope $message, \Throwable $throwable = null)`.
69+
* The signature of method `RetryStrategyInterface::getWaitingTime()` has been updated to `RetryStrategyInterface::getWaitingTime(Envelope $message, \Throwable $throwable = null)`.
6870

6971
PhpUnitBridge
7072
-------------

‎src/Symfony/Component/Messenger/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* Moved AmqpExt transport to package `symfony/amqp-messenger`. All classes in `Symfony\Component\Messenger\Transport\AmqpExt` have been moved to `Symfony\Component\Messenger\Bridge\Amqp\Transport`
88
* Moved Doctrine transport to package `symfony/doctrine-messenger`. All classes in `Symfony\Component\Messenger\Transport\Doctrine` have been moved to `Symfony\Component\Messenger\Bridge\Doctrine\Transport`
99
* Moved RedisExt transport to package `symfony/redis-messenger`. All classes in `Symfony\Component\Messenger\Transport\RedisExt` have been moved to `Symfony\Component\Messenger\Bridge\Redis\Transport`
10+
* Added support for passing a `\Throwable` argument to `RetryStrategyInterface` methods. This allows to define strategies based on the reason of the handling failure.
1011

1112
5.0.0
1213
-----

‎src/Symfony/Component/Messenger/EventListener/SendFailedMessageForRetryListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/EventListener/SendFailedMessageForRetryListener.php
+4-2Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ public function onMessageFailed(WorkerMessageFailedEvent $event)
5858
$event->setForRetry();
5959

6060
++$retryCount;
61-
$delay = $retryStrategy->getWaitingTime($envelope);
61+
62+
$delay = $retryStrategy->getWaitingTime($envelope, $throwable);
63+
6264
if (null !== $this->logger) {
6365
$this->logger->error('Error thrown while handling message {class}. Sending for retry #{retryCount} using {delay} ms delay. Error: "{error}"', $context + ['retryCount' => $retryCount, 'delay' => $delay, 'error' => $throwable->getMessage(), 'exception' => $throwable]);
6466
}
@@ -103,7 +105,7 @@ private function shouldRetry(\Throwable $e, Envelope $envelope, RetryStrategyInt
103105
return false;
104106
}
105107

106-
return $retryStrategy->isRetryable($envelope);
108+
return $retryStrategy->isRetryable($envelope, $e);
107109
}
108110

109111
private function getRetryStrategyForTransport(string $alias): ?RetryStrategyInterface

‎src/Symfony/Component/Messenger/Retry/MultiplierRetryStrategy.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Retry/MultiplierRetryStrategy.php
+8-2Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,20 @@ public function __construct(int $maxRetries = 3, int $delayMilliseconds = 1000,
6363
$this->maxDelayMilliseconds = $maxDelayMilliseconds;
6464
}
6565

66-
public function isRetryable(Envelope $message): bool
66+
/**
67+
* @param \Throwable|null $throwable The cause of the failed handling
68+
*/
69+
public function isRetryable(Envelope $message, \Throwable $throwable = null): bool
6770
{
6871
$retries = RedeliveryStamp::getRetryCountFromEnvelope($message);
6972

7073
return $retries < $this->maxRetries;
7174
}
7275

73-
public function getWaitingTime(Envelope $message): int
76+
/**
77+
* @param \Throwable|null $throwable The cause of the failed handling
78+
*/
79+
public function getWaitingTime(Envelope $message, \Throwable $throwable = null): int
7480
{
7581
$retries = RedeliveryStamp::getRetryCountFromEnvelope($message);
7682

‎src/Symfony/Component/Messenger/Retry/RetryStrategyInterface.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Retry/RetryStrategyInterface.php
+7-2Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@
2020
*/
2121
interface RetryStrategyInterface
2222
{
23-
public function isRetryable(Envelope $message): bool;
23+
/**
24+
* @param \Throwable|null $throwable The cause of the failed handling
25+
*/
26+
public function isRetryable(Envelope $message/*, \Throwable $throwable = null*/): bool;
2427

2528
/**
29+
* @param \Throwable|null $throwable The cause of the failed handling
30+
*
2631
* @return int The time to delay/wait in milliseconds
2732
*/
28-
public function getWaitingTime(Envelope $message): int;
33+
public function getWaitingTime(Envelope $message/*, \Throwable $throwable = null*/): int;
2934
}

‎src/Symfony/Component/Messenger/Tests/EventListener/SendFailedMessageForRetryListenerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Tests/EventListener/SendFailedMessageForRetryListenerTest.php
+37Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,41 @@ public function testEnvelopeIsSentToTransportOnRetry()
7676

7777
$listener->onMessageFailed($event);
7878
}
79+
80+
public function testEnvelopeIsSentToTransportOnRetryWithExceptionPassedToRetryStrategy()
81+
{
82+
$exception = new \Exception('no!');
83+
$envelope = new Envelope(new \stdClass());
84+
85+
$sender = $this->createMock(SenderInterface::class);
86+
$sender->expects($this->once())->method('send')->willReturnCallback(function (Envelope $envelope) {
87+
/** @var DelayStamp $delayStamp */
88+
$delayStamp = $envelope->last(DelayStamp::class);
89+
/** @var RedeliveryStamp $redeliveryStamp */
90+
$redeliveryStamp = $envelope->last(RedeliveryStamp::class);
91+
92+
$this->assertInstanceOf(DelayStamp::class, $delayStamp);
93+
$this->assertSame(1000, $delayStamp->getDelay());
94+
95+
$this->assertInstanceOf(RedeliveryStamp::class, $redeliveryStamp);
96+
$this->assertSame(1, $redeliveryStamp->getRetryCount());
97+
98+
return $envelope;
99+
});
100+
$senderLocator = $this->createMock(ContainerInterface::class);
101+
$senderLocator->expects($this->once())->method('has')->willReturn(true);
102+
$senderLocator->expects($this->once())->method('get')->willReturn($sender);
103+
$retryStategy = $this->createMock(RetryStrategyInterface::class);
104+
$retryStategy->expects($this->once())->method('isRetryable')->with($envelope, $exception)->willReturn(true);
105+
$retryStategy->expects($this->once())->method('getWaitingTime')->with($envelope, $exception)->willReturn(1000);
106+
$retryStrategyLocator = $this->createMock(ContainerInterface::class);
107+
$retryStrategyLocator->expects($this->once())->method('has')->willReturn(true);
108+
$retryStrategyLocator->expects($this->once())->method('get')->willReturn($retryStategy);
109+
110+
$listener = new SendFailedMessageForRetryListener($senderLocator, $retryStrategyLocator);
111+
112+
$event = new WorkerMessageFailedEvent($envelope, 'my_receiver', $exception);
113+
114+
$listener->onMessageFailed($event);
115+
}
79116
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.