Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit96e3c84

Browse files
committed
[Messenger] Add jitter parameter to MultiplierRetryStrategy
1 parentccbdc1a commit96e3c84

File tree

6 files changed

+54
-3
lines changed

6 files changed

+54
-3
lines changed

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1586,6 +1586,7 @@ function ($a) {
15861586
->integerNode('delay')->defaultValue(1000)->min(0)->info('Time in ms to delay (or the initial value when multiplier is used)')->end()
15871587
->floatNode('multiplier')->defaultValue(2)->min(1)->info('If greater than 1, delay will grow exponentially for each retry: this delay = (delay * (multiple ^ retries))')->end()
15881588
->integerNode('max_delay')->defaultValue(0)->min(0)->info('Max time in ms that a retry should ever be delayed (0 = infinite)')->end()
1589+
->floatNode('jitter')->defaultValue(0.1)->min(0)->max(1)->info('Randomness in percent (between 0 and 1) to apply to the delay')->end()
15891590
->end()
15901591
->end()
15911592
->scalarNode('rate_limiter')

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2195,7 +2195,8 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder
21952195
->replaceArgument(0,$transport['retry_strategy']['max_retries'])
21962196
->replaceArgument(1,$transport['retry_strategy']['delay'])
21972197
->replaceArgument(2,$transport['retry_strategy']['multiplier'])
2198-
->replaceArgument(3,$transport['retry_strategy']['max_delay']);
2198+
->replaceArgument(3,$transport['retry_strategy']['max_delay'])
2199+
->replaceArgument(4,$transport['retry_strategy']['jitter']);
21992200
$container->setDefinition($retryServiceId,$retryDefinition);
22002201

22012202
$transportRetryReferences[$name] =newReference($retryServiceId);

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@
160160
abstract_arg('delay ms'),
161161
abstract_arg('multiplier'),
162162
abstract_arg('max delay ms'),
163+
abstract_arg('jitter'),
163164
])
164165

165166
// rate limiter

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* Add option`redis_sentinel` as an alias for`sentinel_master`
88
* Add`--all` option to the`messenger:consume` command
99
* Make`#[AsMessageHandler]` final
10+
* Add parameter`$jitter` to`MultiplierRetryStrategy` in order to randomize delay and prevent the thundering herd effect.
1011

1112
7.0
1213
---

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,16 @@ class MultiplierRetryStrategy implements RetryStrategyInterface
3636
privateint$delayMilliseconds;
3737
privatefloat$multiplier;
3838
privateint$maxDelayMilliseconds;
39+
privatefloat$jitter;
3940

4041
/**
4142
* @param int $maxRetries The maximum number of times to retry
4243
* @param int $delayMilliseconds Amount of time to delay (or the initial value when multiplier is used)
4344
* @param float $multiplier Multiplier to apply to the delay each time a retry occurs
4445
* @param int $maxDelayMilliseconds Maximum delay to allow (0 means no maximum)
46+
* @param float $jitter Probability of randomness int delay (0 = none, 1 = 100% random)
4547
*/
46-
publicfunction__construct(int$maxRetries =3,int$delayMilliseconds =1000,float$multiplier =1,int$maxDelayMilliseconds =0)
48+
publicfunction__construct(int$maxRetries =3,int$delayMilliseconds =1000,float$multiplier =1,int$maxDelayMilliseconds =0,float$jitter =0.1)
4749
{
4850
$this->maxRetries =$maxRetries;
4951

@@ -61,6 +63,11 @@ public function __construct(int $maxRetries = 3, int $delayMilliseconds = 1000,
6163
thrownewInvalidArgumentException(sprintf('Max delay must be greater than or equal to zero: "%s" given.',$maxDelayMilliseconds));
6264
}
6365
$this->maxDelayMilliseconds =$maxDelayMilliseconds;
66+
67+
if ($jitter <0 ||$jitter >1) {
68+
thrownewInvalidArgumentException(sprintf('Jitter must be between 0 and 1: "%s" given.',$jitter));
69+
}
70+
$this->jitter =$jitter;
6471
}
6572

6673
/**
@@ -82,6 +89,11 @@ public function getWaitingTime(Envelope $message, \Throwable $throwable = null):
8289

8390
$delay =$this->delayMilliseconds *$this->multiplier **$retries;
8491

92+
if ($this->jitter >0) {
93+
$randomness = (int) ($delay *$this->jitter);
94+
$delay +=random_int(-$randomness, +$randomness);
95+
}
96+
8597
if ($delay >$this->maxDelayMilliseconds &&0 !==$this->maxDelayMilliseconds) {
8698
return$this->maxDelayMilliseconds;
8799
}

‎src/Symfony/Component/Messenger/Tests/Retry/MultiplierRetryStrategyTest.php‎

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function testIsRetryableWithNoStamp()
5454
*/
5555
publicfunctiontestGetWaitTime(int$delay,float$multiplier,int$maxDelay,int$previousRetries,int$expectedDelay)
5656
{
57-
$strategy =newMultiplierRetryStrategy(10,$delay,$multiplier,$maxDelay);
57+
$strategy =newMultiplierRetryStrategy(10,$delay,$multiplier,$maxDelay,0);
5858
$envelope =newEnvelope(new \stdClass(), [newRedeliveryStamp($previousRetries)]);
5959

6060
$this->assertSame($expectedDelay,$strategy->getWaitingTime($envelope));
@@ -89,4 +89,39 @@ public static function getWaitTimeTests(): iterable
8989
yield [1000,1.5555,5000,1,1556];
9090
yield [1000,1.5555,5000,2,2420];
9191
}
92+
93+
/**
94+
* @dataProvider getJitterTest
95+
*/
96+
publicfunctiontestJitter(float$jitter,int$maxMin,int$maxMax)
97+
{
98+
$strategy =newMultiplierRetryStrategy(3,1000,1,0,$jitter);
99+
$envelope =newEnvelope(new \stdClass());
100+
101+
$min =1000;
102+
$max =1000;
103+
for ($i =0;$i <100; ++$i) {
104+
$delay =$strategy->getWaitingTime($envelope);
105+
$min =min($min,$delay);
106+
$max =max($max,$delay);
107+
}
108+
109+
$this->assertGreaterThanOrEqual($maxMin,$min);
110+
$this->assertLessThanOrEqual($maxMax,$max);
111+
}
112+
113+
publicstaticfunctiongetJitterTest():iterable
114+
{
115+
yield [1.0,0,2000];
116+
yield [0.9,100,1900];
117+
yield [0.8,200,1800];
118+
yield [0.7,300,1700];
119+
yield [0.6,400,1600];
120+
yield [0.5,500,1500];
121+
yield [0.4,600,1400];
122+
yield [0.3,700,1300];
123+
yield [0.2,800,1200];
124+
yield [0.1,900,1100];
125+
yield [0.0,1000,1000];
126+
}
92127
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp