Skip to content

Commit 85ffb86

Browse files
author
Karl Rieb
committed
Add small backoff jitter to retrriable requests to avoid stampeding herd problem.
1 parent 40fd4cb commit 85ffb86

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

src/main/java/com/dropbox/core/DbxRequestUtil.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.util.ArrayList;
1414
import java.util.List;
1515
import java.util.Map;
16+
import java.util.Random;
1617

1718
import com.dropbox.core.stone.StoneSerializer;
1819
import com.dropbox.core.http.HttpRequestor;
@@ -27,6 +28,7 @@
2728
/*>>> import checkers.nullness.quals.Nullable; */
2829

2930
public final class DbxRequestUtil {
31+
private static final Random RAND = new Random();
3032

3133
public static String encodeUrlParam(String s) {
3234
try {
@@ -442,6 +444,10 @@ public static <T, E extends Throwable> T runAndRetry(int maxRetries, RequestMake
442444
throw thrown;
443445
}
444446

447+
// add a random jitter to the backoff to avoid stampeding herd. This is especially
448+
// useful for ServerExceptions, where backoff is 0.
449+
backoff += RAND.nextInt(1000);
450+
445451
if (backoff > 0L) {
446452
try {
447453
Thread.sleep(backoff);

src/main/java/com/dropbox/core/v2/DbxRawClientV2.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.Arrays;
2929
import java.util.Collections;
3030
import java.util.List;
31+
import java.util.Random;
3132

3233
/*>>> import checkers.nullness.quals.NonNull; */
3334
/*>>> import checkers.nullness.quals.Nullable; */
@@ -49,6 +50,7 @@ public abstract class DbxRawClientV2 {
4950
// The HTTP status codes returned for errors specific to particular API calls.
5051
private static final List<Integer> FUNCTION_SPECIFIC_ERROR_CODES = Arrays.asList(403, 404, 409);
5152
private static final JsonFactory JSON = new JsonFactory();
53+
private static final Random RAND = new Random();
5254

5355
private final DbxRequestConfig requestConfig;
5456
private final DbxHost host;
@@ -259,21 +261,26 @@ private static <T> T executeRetriable(int maxRetries, RetriableExecution<T> exec
259261
} catch (RetryException ex) {
260262
if (retries < maxRetries) {
261263
++retries;
262-
sleepQuietly(ex.getBackoffMillis());
264+
sleepQuietlyWithJitter(ex.getBackoffMillis());
263265
} else {
264266
throw ex;
265267
}
266268
}
267269
}
268270
}
269271

270-
private static void sleepQuietly(long millis) {
271-
if (millis <= 0) {
272+
private static void sleepQuietlyWithJitter(long millis) {
273+
// add a small jitter to the sleep to avoid stampeding herd problem, especially when millis
274+
// is 0.
275+
long jitter = RAND.nextInt(1000);
276+
long sleepMillis = millis + jitter;
277+
278+
if (sleepMillis <= 0) {
272279
return;
273280
}
274281

275282
try {
276-
Thread.sleep(millis);
283+
Thread.sleep(sleepMillis);
277284
} catch (InterruptedException ex) {
278285
// preserve interrupt
279286
Thread.currentThread().interrupt();

0 commit comments

Comments
 (0)