GH-126: ExpRandomBackOffPolicy: fix maxInterval

Fixes https://github.com/spring-projects/spring-retry/issues/126

The `ExponentialRandomBackOffPolicy` doesn't take into account a `maxInterval` for the next `sleep`
causing a very long sleep problem eventually

* Fallback to `super.getMaxInterval()` when `next` from random is too big
* Fix JavaDocs for ranges
* Add test for `maxInterval`
This commit is contained in:
Chase Diem
2019-10-22 11:02:57 -04:00
committed by Artem Bilan
parent 5a1a3bfbf3
commit ff4535fecf
3 changed files with 28 additions and 1 deletions

0
git Normal file
View File

View File

@@ -37,10 +37,12 @@ import java.util.Random;
* {@link ExponentialBackOffPolicy} yields: [50, 100, 200, 400, 800]
*
* {@link ExponentialRandomBackOffPolicy} may yield [76, 151, 304, 580, 901] or [53, 190,
* 267, 451, 815]
* 267, 451, 815] (random distributed values within the ranges of [50-100, 100-200, 200-400,
* 400-800, 800-1600])
*
* @author Jon Travis
* @author Dave Syer
* @author Chase Diem
*/
@SuppressWarnings("serial")
public class ExponentialRandomBackOffPolicy extends ExponentialBackOffPolicy {
@@ -69,6 +71,9 @@ public class ExponentialRandomBackOffPolicy extends ExponentialBackOffPolicy {
public synchronized long getSleepAndIncrement() {
long next = super.getSleepAndIncrement();
next = (long) (next * (1 + r.nextFloat() * (getMultiplier() - 1)));
if (next > super.getMaxInterval()) {
next = super.getMaxInterval();
}
return next;
}

View File

@@ -29,6 +29,7 @@ import org.springframework.retry.support.RetrySimulator;
/**
* @author Dave Syer
* @author Jon Travis
* @author Chase Diem
*
*/
public class ExponentialRandomBackOffPolicyTests {
@@ -68,6 +69,27 @@ public class ExponentialRandomBackOffPolicyTests {
}
}
@Test
public void testMaxInterval() throws Exception {
ExponentialBackOffPolicy backOffPolicy = makeBackoffPolicy();
backOffPolicy.setInitialInterval(3000);
long maxInterval = backOffPolicy.getMaxInterval();
RetrySimulator simulator = new RetrySimulator(backOffPolicy, makeRetryPolicy());
RetrySimulation simulation = simulator.executeSimulation(1);
List<Long> sleeps = simulation.getLongestTotalSleepSequence().getSleeps();
System.out.println("Single trial of " + backOffPolicy + ": sleeps=" + sleeps);
assertEquals(MAX_RETRIES - 1, sleeps.size());
long initialInterval = backOffPolicy.getInitialInterval();
for (int i = 0; i < sleeps.size(); i++) {
long expectedMaxValue = 2 * (long) (initialInterval
+ initialInterval * Math.max(1, Math.pow(backOffPolicy.getMultiplier(), i)));
assertTrue("Found a sleep [" + sleeps.get(i) + "] which exceeds our max interval value of "
+ expectedMaxValue + " at interval " + i, sleeps.get(i) <= maxInterval);
}
}
@Test
public void testMultiBackOff() throws Exception {
ExponentialBackOffPolicy backOffPolicy = makeBackoffPolicy();