Repository: jclouds Updated Branches: refs/heads/master c902fbf90 -> f5523c941
Fixes the exponential backoff for small delay values Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/f5523c94 Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/f5523c94 Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/f5523c94 Branch: refs/heads/master Commit: f5523c9412c7b0e88a88b1c533bf86d58905ce15 Parents: c902fbf Author: Zack Shoylev <[email protected]> Authored: Tue Jan 13 19:06:56 2015 -0600 Committer: Zack Shoylev <[email protected]> Committed: Wed Jan 21 16:50:01 2015 -0600 ---------------------------------------------------------------------- .../handlers/BackoffLimitedRetryHandler.java | 10 ++++-- .../BackoffLimitedRetryHandlerTest.java | 38 +++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/f5523c94/core/src/main/java/org/jclouds/http/handlers/BackoffLimitedRetryHandler.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/jclouds/http/handlers/BackoffLimitedRetryHandler.java b/core/src/main/java/org/jclouds/http/handlers/BackoffLimitedRetryHandler.java index 4dac50f..481cde2 100644 --- a/core/src/main/java/org/jclouds/http/handlers/BackoffLimitedRetryHandler.java +++ b/core/src/main/java/org/jclouds/http/handlers/BackoffLimitedRetryHandler.java @@ -16,6 +16,7 @@ */ package org.jclouds.http.handlers; +import static java.lang.Math.max; import static org.jclouds.http.HttpUtils.releasePayload; import java.io.IOException; @@ -124,10 +125,16 @@ public class BackoffLimitedRetryHandler implements HttpRetryHandler, IOException public void imposeBackoffExponentialDelay(long period, long maxPeriod, int pow, int failureCount, int max, String commandDescription) { + if (period == 0) { + // Essentially disables the exponential backoff + logger.debug("Retry %d/%d: delaying for %d ms: %s", failureCount, max, 0, commandDescription); + return; + } long delayMs = (long) (period * Math.pow(failureCount, pow)); // Add random delay to avoid thundering herd problem when multiple // simultaneous failed requests retry after sleeping for the same delay. - delayMs += new Random().nextInt((int) (delayMs / 10)); + // Throws an exception for a value of 0 + delayMs += new Random().nextInt((int) (max(delayMs / 10, 1) )); delayMs = delayMs > maxPeriod ? maxPeriod : delayMs; logger.debug("Retry %d/%d: delaying for %d ms: %s", failureCount, max, delayMs, commandDescription); try { @@ -136,5 +143,4 @@ public class BackoffLimitedRetryHandler implements HttpRetryHandler, IOException Throwables.propagate(e); } } - } http://git-wip-us.apache.org/repos/asf/jclouds/blob/f5523c94/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java b/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java index f421016..4e2bfe6 100644 --- a/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java +++ b/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java @@ -81,6 +81,42 @@ public class BackoffLimitedRetryHandlerTest { } @Test + void testExponentialBackoffDelaySmallInterval5() throws InterruptedException { + long period = 5; + long acceptableDelay = period - 1; + + long startTime = System.nanoTime(); + handler.imposeBackoffExponentialDelay(period, 2, 1, 5, "TEST FAILURE: 1"); + long elapsedTime = (System.nanoTime() - startTime) / 1000000; + assert elapsedTime >= period - 1 : elapsedTime; + assertTrue(elapsedTime < period + acceptableDelay); + } + + @Test + void testExponentialBackoffDelaySmallInterval1() throws InterruptedException { + long period = 1; + long acceptableDelay = 5; + + long startTime = System.nanoTime(); + handler.imposeBackoffExponentialDelay(period, 2, 1, 5, "TEST FAILURE: 1"); + long elapsedTime = (System.nanoTime() - startTime) / 1000000; + assert elapsedTime >= period - 1 : elapsedTime; + assertTrue(elapsedTime < period + acceptableDelay); + } + + @Test + void testExponentialBackoffDelaySmallInterval0() throws InterruptedException { + long period = 0; + long acceptableDelay = 5; + + long startTime = System.nanoTime(); + handler.imposeBackoffExponentialDelay(period, 2, 1, 5, "TEST FAILURE: 1"); + long elapsedTime = (System.nanoTime() - startTime) / 1000000; + assert elapsedTime >= period - 1 : elapsedTime; + assertTrue(elapsedTime < period + acceptableDelay); + } + + @Test void testClosesInputStream() throws InterruptedException, IOException, SecurityException, NoSuchMethodException { HttpCommand command = createCommand(); @@ -126,7 +162,7 @@ public class BackoffLimitedRetryHandlerTest { private final Function<Invocation, HttpRequest> processor = ContextBuilder .newBuilder(AnonymousProviderMetadata.forApiOnEndpoint(IntegrationTestClient.class, "http://localhost")) .buildInjector().getInstance(RestAnnotationProcessor.class); - + private HttpCommand createCommand() throws SecurityException, NoSuchMethodException { Invokable<IntegrationTestClient, String> method = method(IntegrationTestClient.class, "download", String.class);
