Skip to content

Commit d01f25b

Browse files
authored
GH-397: Fix exponential backoff for initial supplier
Fixes #397 `Retryable` with exponential backoff not working with `delayExpression` The `ExponentialBackOffContext` when we are calling `getSleepAndIncrement` `sleep` value resolved from `intervalSupplier` if it is not null. But further when we resolving `getNextInterval`, we assigning it to the `interval` instead of `intervalSupplier` and `interval` keeps it initial value for the next iteration. * Assign `intervalSupplier` result into an `interval` on a first `getInterval()` call
1 parent 13879ce commit d01f25b

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

src/main/java/org/springframework/retry/backoff/ExponentialBackOffPolicy.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
* @author Gary Russell
4343
* @author Artem Bilan
4444
* @author Marius Lichtblau
45+
* @author Anton Aharkau
4546
*/
4647
@SuppressWarnings("serial")
4748
public class ExponentialBackOffPolicy implements SleepingBackOffPolicy<ExponentialBackOffPolicy> {
@@ -259,7 +260,7 @@ static class ExponentialBackOffContext implements BackOffContext {
259260

260261
private final long maxInterval;
261262

262-
private Supplier<Long> intervalSupplier;
263+
private Supplier<Long> initialIntervalSupplier;
263264

264265
private Supplier<Double> multiplierSupplier;
265266

@@ -271,7 +272,7 @@ public ExponentialBackOffContext(long interval, double multiplier, long maxInter
271272
this.interval = interval;
272273
this.multiplier = multiplier;
273274
this.maxInterval = maxInterval;
274-
this.intervalSupplier = intervalSupplier;
275+
this.initialIntervalSupplier = intervalSupplier;
275276
this.multiplierSupplier = multiplierSupplier;
276277
this.maxIntervalSupplier = maxIntervalSupplier;
277278
}
@@ -297,7 +298,11 @@ public double getMultiplier() {
297298
}
298299

299300
public long getInterval() {
300-
return this.intervalSupplier != null ? this.intervalSupplier.get() : this.interval;
301+
if (this.initialIntervalSupplier != null) {
302+
this.interval = this.initialIntervalSupplier.get();
303+
this.initialIntervalSupplier = null;
304+
}
305+
return this.interval;
301306
}
302307

303308
public long getMaxInterval() {

src/test/java/org/springframework/retry/annotation/EnableRetryTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
* @author Aldo Sinanaj
6060
* @author Henning Pöttker
6161
* @author Yanming Zhou
62+
* @author Anton Aharkau
6263
* @since 1.1
6364
*/
6465
public class EnableRetryTests {
@@ -295,7 +296,7 @@ void runtimeExpressions() throws Exception {
295296
service.service6();
296297
RuntimeConfigs runtime = context.getBean(RuntimeConfigs.class);
297298
verify(runtime, times(5)).getMaxAttempts();
298-
verify(runtime, times(2)).getInitial();
299+
verify(runtime, times(1)).getInitial();
299300
verify(runtime, times(2)).getMax();
300301
verify(runtime, times(2)).getMult();
301302

src/test/java/org/springframework/retry/backoff/ExponentialBackOffPolicyTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* @author Dave Syer
2727
* @author Gary Russell
2828
* @author Marius Lichtblau
29+
* @author Anton Aharkau
2930
*/
3031
public class ExponentialBackOffPolicyTests {
3132

@@ -94,6 +95,22 @@ public void testMultiBackOff() {
9495
}
9596
}
9697

98+
@Test
99+
public void testMultiBackOffWithInitialDelaySupplier() {
100+
ExponentialBackOffPolicy strategy = new ExponentialBackOffPolicy();
101+
long seed = 40;
102+
double multiplier = 1.2;
103+
strategy.initialIntervalSupplier(() -> 40L);
104+
strategy.setMultiplier(multiplier);
105+
strategy.setSleeper(sleeper);
106+
BackOffContext context = strategy.start(null);
107+
for (int x = 0; x < 5; x++) {
108+
strategy.backOff(context);
109+
assertThat(sleeper.getLastBackOff()).isEqualTo(seed);
110+
seed *= multiplier;
111+
}
112+
}
113+
97114
@Test
98115
public void testInterruptedStatusIsRestored() {
99116
ExponentialBackOffPolicy strategy = new ExponentialBackOffPolicy();

0 commit comments

Comments
 (0)