Skip to content

Commit 395a30b

Browse files
committed
retry: add the ability to cap the maxRetryFactor. fix left-shifts so they don't go negative.
Signed-off-by: Ken McCracken <ken.mccracken@here.com>
1 parent 36b1127 commit 395a30b

2 files changed

Lines changed: 55 additions & 3 deletions

File tree

here-oauth-client/src/main/java/com/here/account/oauth2/retry/Socket5xxExponentialRandomBackoffPolicy.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,25 @@ public class Socket5xxExponentialRandomBackoffPolicy implements RetryPolicy {
1111

1212
public static final int DEFAULT_MAX_NO_RETRIES = 3;
1313
public static final int DEFAULT_RETRY_INTERVAL_MILLIS = 1000;
14+
public static final int DEFAULT_MAX_RETRY_FACTOR = 1 << 30;
1415

1516
private final int maxNumberOfRetries;
1617
private final int retryIntervalMillis;
18+
private final int maxRetryFactor;
1719

1820
public Socket5xxExponentialRandomBackoffPolicy(){
19-
this.maxNumberOfRetries = DEFAULT_MAX_NO_RETRIES;
20-
this.retryIntervalMillis = DEFAULT_RETRY_INTERVAL_MILLIS;
21+
this(DEFAULT_MAX_NO_RETRIES, DEFAULT_RETRY_INTERVAL_MILLIS);
2122
}
2223

2324
public Socket5xxExponentialRandomBackoffPolicy(int maxNumberOfRetries, int retryIntervalMillis){
25+
this(maxNumberOfRetries, retryIntervalMillis, DEFAULT_MAX_RETRY_FACTOR);
26+
}
27+
28+
public Socket5xxExponentialRandomBackoffPolicy(int maxNumberOfRetries, int retryIntervalMillis,
29+
int maxRetryFactor) {
2430
this.maxNumberOfRetries = maxNumberOfRetries;
2531
this.retryIntervalMillis = retryIntervalMillis;
32+
this.maxRetryFactor = maxRetryFactor;
2633
}
2734

2835
@Override
@@ -36,7 +43,8 @@ public boolean shouldRetry(RetryContext retryContext) {
3643

3744
@Override
3845
public int getNextRetryIntervalMillis(RetryContext retryContext){
39-
int factor = 1 << (retryContext.getRetryCount());
46+
int retryCount = retryContext.getRetryCount();
47+
int factor = Math.min(1 << (Math.min(retryCount, 30)), maxRetryFactor);
4048
return retryIntervalMillis * ThreadLocalRandom.current().nextInt(factor);
4149
}
4250
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.here.account.oauth2.retry;
2+
3+
import org.junit.Before;
4+
import org.junit.Test;
5+
import org.mockito.Mockito;
6+
import java.net.SocketTimeoutException;
7+
import com.here.account.http.HttpProvider;
8+
9+
import static org.junit.Assert.assertTrue;
10+
11+
public class Socket5xxExponentialRandomBackoffPolicyTest {
12+
13+
private Socket5xxExponentialRandomBackoffPolicy socket5xxExponentialRandomBackoffPolicy;
14+
int maxNumberOfRetries = Integer.MAX_VALUE;
15+
int retryIntervalMillis = 500;
16+
int maxRetryFactor = 5;
17+
18+
@Before
19+
public void setUp() {
20+
this.socket5xxExponentialRandomBackoffPolicy =
21+
new Socket5xxExponentialRandomBackoffPolicy( maxNumberOfRetries, retryIntervalMillis,
22+
maxRetryFactor);
23+
}
24+
25+
@Test
26+
public void test_shouldRetry() {
27+
HttpProvider.HttpResponse httpResponse = Mockito.mock(HttpProvider.HttpResponse.class);
28+
Mockito.when(httpResponse.getStatusCode()).thenReturn(503);
29+
Exception lastException = Mockito.mock(SocketTimeoutException.class);
30+
RetryContext retryContext = new RetryContext();
31+
retryContext.setLastRetryResponse(httpResponse);
32+
retryContext.setLastException(lastException);
33+
final int maxRetryIntervalMillis = maxRetryFactor * retryIntervalMillis;
34+
for (int i = 0; i < 1000; i++) {
35+
retryContext.incrementRetryCount();
36+
assertTrue("shouldRetry should have been true",
37+
socket5xxExponentialRandomBackoffPolicy.shouldRetry(retryContext));
38+
int nextRetryIntervalMillis = socket5xxExponentialRandomBackoffPolicy.getNextRetryIntervalMillis(retryContext);
39+
assertTrue("unexpected nextRetryIntervalMillis "
40+
+ nextRetryIntervalMillis + ", should be >= 0 and <= " + maxRetryIntervalMillis,
41+
nextRetryIntervalMillis >= 0 && nextRetryIntervalMillis <= maxRetryIntervalMillis);
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)