下面列出了怎么用org.springframework.util.backoff.ExponentialBackOff的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void startReturnDifferentInstances() {
ExponentialBackOff backOff = new ExponentialBackOff();
backOff.setInitialInterval(2000L);
backOff.setMultiplier(2.0);
backOff.setMaxElapsedTime(4000L);
BackOffExecution execution = backOff.start();
BackOffExecution execution2 = backOff.start();
assertEquals(2000L, execution.nextBackOff());
assertEquals(2000L, execution2.nextBackOff());
assertEquals(4000L, execution.nextBackOff());
assertEquals(4000L, execution2.nextBackOff());
assertEquals(BackOffExecution.STOP, execution.nextBackOff());
assertEquals(BackOffExecution.STOP, execution2.nextBackOff());
}
@Test
public void startReturnDifferentInstances() {
ExponentialBackOff backOff = new ExponentialBackOff();
backOff.setInitialInterval(2000L);
backOff.setMultiplier(2.0);
backOff.setMaxElapsedTime(4000L);
BackOffExecution execution = backOff.start();
BackOffExecution execution2 = backOff.start();
assertEquals(2000L, execution.nextBackOff());
assertEquals(2000L, execution2.nextBackOff());
assertEquals(4000L, execution.nextBackOff());
assertEquals(4000L, execution2.nextBackOff());
assertEquals(BackOffExecution.STOP, execution.nextBackOff());
assertEquals(BackOffExecution.STOP, execution2.nextBackOff());
}
@Test
public void startReturnDifferentInstances() {
ExponentialBackOff backOff = new ExponentialBackOff();
backOff.setInitialInterval(2000L);
backOff.setMultiplier(2.0);
backOff.setMaxElapsedTime(4000L);
BackOffExecution execution = backOff.start();
BackOffExecution execution2 = backOff.start();
assertEquals(2000l, execution.nextBackOff());
assertEquals(2000l, execution2.nextBackOff());
assertEquals(4000l, execution.nextBackOff());
assertEquals(4000l, execution2.nextBackOff());
assertEquals(BackOffExecution.STOP, execution.nextBackOff());
assertEquals(BackOffExecution.STOP, execution2.nextBackOff());
}
/**
* Configure a {@link BackOff} for the after rollback processor, based on the consumer
* retry properties. If retry is disabled, return a {@link BackOff} that disables
* retry. Otherwise calculate the {@link ExponentialBackOff#setMaxElapsedTime(long)}
* so that the {@link BackOff} stops after the configured
* {@link ExtendedConsumerProperties#getMaxAttempts()}.
* @param extendedConsumerProperties the properties.
* @return the backoff.
*/
private BackOff createBackOff(
final ExtendedConsumerProperties<KafkaConsumerProperties> extendedConsumerProperties) {
int maxAttempts = extendedConsumerProperties.getMaxAttempts();
if (maxAttempts < 2) {
return new FixedBackOff(0L, 0L);
}
int initialInterval = extendedConsumerProperties.getBackOffInitialInterval();
double multiplier = extendedConsumerProperties.getBackOffMultiplier();
int maxInterval = extendedConsumerProperties.getBackOffMaxInterval();
ExponentialBackOff backOff = new ExponentialBackOff(initialInterval, multiplier);
backOff.setMaxInterval(maxInterval);
long maxElapsed = extendedConsumerProperties.getBackOffInitialInterval();
double accum = maxElapsed;
for (int i = 1; i < maxAttempts - 1; i++) {
accum = accum * multiplier;
if (accum > maxInterval) {
accum = maxInterval;
}
maxElapsed += accum;
}
backOff.setMaxElapsedTime(maxElapsed);
return backOff;
}
public <T> T retry(String description, Callable<T> callable) throws Exception {
ExponentialBackOff backOff =
new ExponentialBackOff(
retryConfiguration.getInitialBackoffMillis(),
retryConfiguration.getRetryMultiplier());
backOff.setMaxElapsedTime(retryConfiguration.getMaxBackoffMillis());
BackOffExecution backOffExec = backOff.start();
while (true) {
try {
return callable.call();
} catch (Throwable e) {
long waitTime = backOffExec.nextBackOff();
if (waitTime == BackOffExecution.STOP) {
throw e;
}
log.warn(description + " failed. Retrying in " + waitTime + "ms", e);
TimeUnit.MILLISECONDS.sleep(waitTime);
}
}
}
@Test
public void defaultInstance() {
ExponentialBackOff backOff = new ExponentialBackOff();
BackOffExecution execution = backOff.start();
assertEquals(2000L, execution.nextBackOff());
assertEquals(3000L, execution.nextBackOff());
assertEquals(4500L, execution.nextBackOff());
}
@Test
public void simpleIncrease() {
ExponentialBackOff backOff = new ExponentialBackOff(100L, 2.0);
BackOffExecution execution = backOff.start();
assertEquals(100L, execution.nextBackOff());
assertEquals(200L, execution.nextBackOff());
assertEquals(400L, execution.nextBackOff());
assertEquals(800L, execution.nextBackOff());
}
@Test
public void fixedIncrease() {
ExponentialBackOff backOff = new ExponentialBackOff(100L, 1.0);
backOff.setMaxElapsedTime(300L);
BackOffExecution execution = backOff.start();
assertEquals(100L, execution.nextBackOff());
assertEquals(100L, execution.nextBackOff());
assertEquals(100L, execution.nextBackOff());
assertEquals(BackOffExecution.STOP, execution.nextBackOff());
}
@Test
public void maxIntervalReached() {
ExponentialBackOff backOff = new ExponentialBackOff(2000L, 2.0);
backOff.setMaxInterval(4000L);
BackOffExecution execution = backOff.start();
assertEquals(2000L, execution.nextBackOff());
assertEquals(4000L, execution.nextBackOff());
assertEquals(4000L, execution.nextBackOff()); // max reached
assertEquals(4000L, execution.nextBackOff());
}
@Test
public void maxAttemptsReached() {
ExponentialBackOff backOff = new ExponentialBackOff(2000L, 2.0);
backOff.setMaxElapsedTime(4000L);
BackOffExecution execution = backOff.start();
assertEquals(2000L, execution.nextBackOff());
assertEquals(4000L, execution.nextBackOff());
assertEquals(BackOffExecution.STOP, execution.nextBackOff()); // > 4 sec wait in total
}
@Test
public void maxIntervalReachedImmediately() {
ExponentialBackOff backOff = new ExponentialBackOff(1000L, 2.0);
backOff.setMaxInterval(50L);
BackOffExecution execution = backOff.start();
assertEquals(50L, execution.nextBackOff());
assertEquals(50L, execution.nextBackOff());
}
@Test
public void toStringContent() {
ExponentialBackOff backOff = new ExponentialBackOff(2000L, 2.0);
BackOffExecution execution = backOff.start();
assertEquals("ExponentialBackOff{currentInterval=n/a, multiplier=2.0}", execution.toString());
execution.nextBackOff();
assertEquals("ExponentialBackOff{currentInterval=2000ms, multiplier=2.0}", execution.toString());
execution.nextBackOff();
assertEquals("ExponentialBackOff{currentInterval=4000ms, multiplier=2.0}", execution.toString());
}
@Test
public void defaultInstance() {
ExponentialBackOff backOff = new ExponentialBackOff();
BackOffExecution execution = backOff.start();
assertEquals(2000L, execution.nextBackOff());
assertEquals(3000L, execution.nextBackOff());
assertEquals(4500L, execution.nextBackOff());
}
@Test
public void simpleIncrease() {
ExponentialBackOff backOff = new ExponentialBackOff(100L, 2.0);
BackOffExecution execution = backOff.start();
assertEquals(100L, execution.nextBackOff());
assertEquals(200L, execution.nextBackOff());
assertEquals(400L, execution.nextBackOff());
assertEquals(800L, execution.nextBackOff());
}
@Test
public void fixedIncrease() {
ExponentialBackOff backOff = new ExponentialBackOff(100L, 1.0);
backOff.setMaxElapsedTime(300L);
BackOffExecution execution = backOff.start();
assertEquals(100L, execution.nextBackOff());
assertEquals(100L, execution.nextBackOff());
assertEquals(100L, execution.nextBackOff());
assertEquals(BackOffExecution.STOP, execution.nextBackOff());
}
@Test
public void maxIntervalReached() {
ExponentialBackOff backOff = new ExponentialBackOff(2000L, 2.0);
backOff.setMaxInterval(4000L);
BackOffExecution execution = backOff.start();
assertEquals(2000L, execution.nextBackOff());
assertEquals(4000L, execution.nextBackOff());
assertEquals(4000L, execution.nextBackOff()); // max reached
assertEquals(4000L, execution.nextBackOff());
}
@Test
public void maxAttemptsReached() {
ExponentialBackOff backOff = new ExponentialBackOff(2000L, 2.0);
backOff.setMaxElapsedTime(4000L);
BackOffExecution execution = backOff.start();
assertEquals(2000L, execution.nextBackOff());
assertEquals(4000L, execution.nextBackOff());
assertEquals(BackOffExecution.STOP, execution.nextBackOff()); // > 4 sec wait in total
}
@Test
public void invalidInterval() {
ExponentialBackOff backOff = new ExponentialBackOff();
thrown.expect(IllegalArgumentException.class);
backOff.setMultiplier(0.9);
}
@Test
public void maxIntervalReachedImmediately() {
ExponentialBackOff backOff = new ExponentialBackOff(1000L, 2.0);
backOff.setMaxInterval(50L);
BackOffExecution execution = backOff.start();
assertEquals(50L, execution.nextBackOff());
assertEquals(50L, execution.nextBackOff());
}
@Test
public void toStringContent() {
ExponentialBackOff backOff = new ExponentialBackOff(2000L, 2.0);
BackOffExecution execution = backOff.start();
assertEquals("ExponentialBackOff{currentInterval=n/a, multiplier=2.0}", execution.toString());
execution.nextBackOff();
assertEquals("ExponentialBackOff{currentInterval=2000ms, multiplier=2.0}", execution.toString());
execution.nextBackOff();
assertEquals("ExponentialBackOff{currentInterval=4000ms, multiplier=2.0}", execution.toString());
}
@Test
public void defaultInstance() {
ExponentialBackOff backOff = new ExponentialBackOff();
BackOffExecution execution = backOff.start();
assertEquals(2000l, execution.nextBackOff());
assertEquals(3000l, execution.nextBackOff());
assertEquals(4500l, execution.nextBackOff());
}
@Test
public void simpleIncrease() {
ExponentialBackOff backOff = new ExponentialBackOff(100L, 2.0);
BackOffExecution execution = backOff.start();
assertEquals(100l, execution.nextBackOff());
assertEquals(200l, execution.nextBackOff());
assertEquals(400l, execution.nextBackOff());
assertEquals(800l, execution.nextBackOff());
}
@Test
public void fixedIncrease() {
ExponentialBackOff backOff = new ExponentialBackOff(100L, 1.0);
backOff.setMaxElapsedTime(300l);
BackOffExecution execution = backOff.start();
assertEquals(100l, execution.nextBackOff());
assertEquals(100l, execution.nextBackOff());
assertEquals(100l, execution.nextBackOff());
assertEquals(BackOffExecution.STOP, execution.nextBackOff());
}
@Test
public void maxIntervalReached() {
ExponentialBackOff backOff = new ExponentialBackOff(2000L, 2.0);
backOff.setMaxInterval(4000L);
BackOffExecution execution = backOff.start();
assertEquals(2000l, execution.nextBackOff());
assertEquals(4000l, execution.nextBackOff());
assertEquals(4000l, execution.nextBackOff()); // max reached
assertEquals(4000l, execution.nextBackOff());
}
@Test
public void maxAttemptsReached() {
ExponentialBackOff backOff = new ExponentialBackOff(2000L, 2.0);
backOff.setMaxElapsedTime(4000L);
BackOffExecution execution = backOff.start();
assertEquals(2000l, execution.nextBackOff());
assertEquals(4000l, execution.nextBackOff());
assertEquals(BackOffExecution.STOP, execution.nextBackOff()); // > 4 sec wait in total
}
@Test
public void invalidInterval() {
ExponentialBackOff backOff = new ExponentialBackOff();
thrown.expect(IllegalArgumentException.class);
backOff.setMultiplier(0.9);
}
@Test
public void maxIntervalReachedImmediately() {
ExponentialBackOff backOff = new ExponentialBackOff(1000L, 2.0);
backOff.setMaxInterval(50L);
BackOffExecution execution = backOff.start();
assertEquals(50L, execution.nextBackOff());
assertEquals(50L, execution.nextBackOff());
}
@Test
public void toStringContent() {
ExponentialBackOff backOff = new ExponentialBackOff(2000L, 2.0);
BackOffExecution execution = backOff.start();
assertEquals("ExponentialBackOff{currentInterval=n/a, multiplier=2.0}", execution.toString());
execution.nextBackOff();
assertEquals("ExponentialBackOff{currentInterval=2000ms, multiplier=2.0}", execution.toString());
execution.nextBackOff();
assertEquals("ExponentialBackOff{currentInterval=4000ms, multiplier=2.0}", execution.toString());
}
@Override
public Response intercept(Chain chain) throws IOException {
ExponentialBackOff backoff = new ExponentialBackOff();
backoff.setMaxElapsedTime(maxElapsedBackoffMs);
BackOffExecution backOffExec = backoff.start();
Response response = null;
long waitTime = 0;
while (waitTime != BackOffExecution.STOP) {
Request request = chain.request();
response = chain.proceed(request);
if (response.isSuccessful()
|| NON_RETRYABLE_METHODS.contains(request.method())
|| response.code() == 404) {
return response;
}
try {
waitTime = backOffExec.nextBackOff();
if (waitTime != BackOffExecution.STOP) {
if (response.body() != null) {
response.body().close();
}
log.warn(
"Request for "
+ request.url().toString()
+ " failed. Backing off for "
+ waitTime
+ "ms");
Thread.sleep(waitTime);
}
} catch (Throwable ignored) {
break;
}
}
return response;
}
@Override
public void execute() throws CommandException {
List<String> commandToExecute = getCommandToExecute();
ExponentialBackOff exponentialBackOff = new ExponentialBackOff(initialInterval, multiplier);
BackOffExecution backOffExecution = exponentialBackOff.start();
int numberOfAttempts = 0;
int exitCode = -1;
while (exitCode !=0 && numberOfAttempts < maxNumberOfAttempts) {
try {
numberOfAttempts++;
exitCode = executeCommand(commandToExecute);
if (exitCode != 0) {
consoleWriter.a("Attempt: ").fg(Ansi.Color.CYAN)
.a(numberOfAttempts).a("/").a(maxNumberOfAttempts).reset()
.a(" failed. ");
if (numberOfAttempts < maxNumberOfAttempts) {
long nextBackOff = backOffExecution.nextBackOff();
consoleWriter.a("Retry in ").fg(Ansi.Color.CYAN).a(nextBackOff / 1000.0).reset().a(" seconds").println();
Thread.sleep(nextBackOff);
} else {
consoleWriter.a("Abort").println();
}
}
} catch (CommandException ce) {
throw ce;
} catch (Throwable t) {
throw new CommandException("Couldn't run command with retry", t);
}
}
if (exitCode != 0) {
throw new CommandWithExitStatusException(exitCode);
}
}