下面列出了怎么用org.springframework.util.backoff.BackOffExecution的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());
}
/**
* Apply the next back-off time using the specified {@link BackOffExecution}.
* <p>Return {@code true} if the back-off period has been applied and a new
* attempt to recover should be made, {@code false} if no further attempt
* should be made.
* @since 4.1
*/
protected boolean applyBackOffTime(BackOffExecution execution) {
if (this.recovering && this.interrupted) {
// Interrupted right before and still failing... give up.
return false;
}
long interval = execution.nextBackOff();
if (interval == BackOffExecution.STOP) {
return false;
}
else {
try {
synchronized (this.lifecycleMonitor) {
this.lifecycleMonitor.wait(interval);
}
}
catch (InterruptedException interEx) {
// Re-interrupt current thread, to allow other threads to react.
Thread.currentThread().interrupt();
if (this.recovering) {
this.interrupted = true;
}
}
return true;
}
}
@Test
public void applyBackOff() {
BackOff backOff = mock(BackOff.class);
BackOffExecution execution = mock(BackOffExecution.class);
given(execution.nextBackOff()).willReturn(BackOffExecution.STOP);
given(backOff.start()).willReturn(execution);
DefaultMessageListenerContainer container = createContainer(createFailingContainerFactory());
container.setBackOff(backOff);
container.start();
assertEquals(true, container.isRunning());
container.refreshConnectionUntilSuccessful();
assertEquals(false, container.isRunning());
verify(backOff).start();
verify(execution).nextBackOff();
}
@Test
public void applyBackOffRetry() {
BackOff backOff = mock(BackOff.class);
BackOffExecution execution = mock(BackOffExecution.class);
given(execution.nextBackOff()).willReturn(50L, BackOffExecution.STOP);
given(backOff.start()).willReturn(execution);
DefaultMessageListenerContainer container = createContainer(createFailingContainerFactory());
container.setBackOff(backOff);
container.start();
container.refreshConnectionUntilSuccessful();
assertEquals(false, container.isRunning());
verify(backOff).start();
verify(execution, times(2)).nextBackOff();
}
@Test
public void recoverResetBackOff() {
BackOff backOff = mock(BackOff.class);
BackOffExecution execution = mock(BackOffExecution.class);
given(execution.nextBackOff()).willReturn(50L, 50L, 50L); // 3 attempts max
given(backOff.start()).willReturn(execution);
DefaultMessageListenerContainer container = createContainer(createRecoverableContainerFactory(1));
container.setBackOff(backOff);
container.start();
container.refreshConnectionUntilSuccessful();
assertEquals(true, container.isRunning());
verify(backOff).start();
verify(execution, times(1)).nextBackOff(); // only on attempt as the second one lead to a recovery
}
@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());
}
/**
* Apply the next back-off time using the specified {@link BackOffExecution}.
* <p>Return {@code true} if the back-off period has been applied and a new
* attempt to recover should be made, {@code false} if no further attempt
* should be made.
* @since 4.1
*/
protected boolean applyBackOffTime(BackOffExecution execution) {
if (this.recovering && this.interrupted) {
// Interrupted right before and still failing... give up.
return false;
}
long interval = execution.nextBackOff();
if (interval == BackOffExecution.STOP) {
return false;
}
else {
try {
synchronized (this.lifecycleMonitor) {
this.lifecycleMonitor.wait(interval);
}
}
catch (InterruptedException interEx) {
// Re-interrupt current thread, to allow other threads to react.
Thread.currentThread().interrupt();
if (this.recovering) {
this.interrupted = true;
}
}
return true;
}
}
@Test
public void applyBackOff() {
BackOff backOff = mock(BackOff.class);
BackOffExecution execution = mock(BackOffExecution.class);
given(execution.nextBackOff()).willReturn(BackOffExecution.STOP);
given(backOff.start()).willReturn(execution);
DefaultMessageListenerContainer container = createContainer(createFailingContainerFactory());
container.setBackOff(backOff);
container.start();
assertEquals(true, container.isRunning());
container.refreshConnectionUntilSuccessful();
assertEquals(false, container.isRunning());
verify(backOff).start();
verify(execution).nextBackOff();
}
@Test
public void applyBackOffRetry() {
BackOff backOff = mock(BackOff.class);
BackOffExecution execution = mock(BackOffExecution.class);
given(execution.nextBackOff()).willReturn(50L, BackOffExecution.STOP);
given(backOff.start()).willReturn(execution);
DefaultMessageListenerContainer container = createContainer(createFailingContainerFactory());
container.setBackOff(backOff);
container.start();
container.refreshConnectionUntilSuccessful();
assertEquals(false, container.isRunning());
verify(backOff).start();
verify(execution, times(2)).nextBackOff();
}
@Test
public void recoverResetBackOff() {
BackOff backOff = mock(BackOff.class);
BackOffExecution execution = mock(BackOffExecution.class);
given(execution.nextBackOff()).willReturn(50L, 50L, 50L); // 3 attempts max
given(backOff.start()).willReturn(execution);
DefaultMessageListenerContainer container = createContainer(createRecoverableContainerFactory(1));
container.setBackOff(backOff);
container.start();
container.refreshConnectionUntilSuccessful();
assertEquals(true, container.isRunning());
verify(backOff).start();
verify(execution, times(1)).nextBackOff(); // only on attempt as the second one lead to a recovery
}
@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());
}
/**
* Apply the next back off time using the specified {@link BackOffExecution}.
* <p>Return {@code true} if the back off period has been applied and a new
* attempt to recover should be made, {@code false} if no further attempt
* should be made.
*/
protected boolean applyBackOffTime(BackOffExecution execution) {
long interval = execution.nextBackOff();
if (interval == BackOffExecution.STOP) {
return false;
}
else {
try {
Thread.sleep(interval);
}
catch (InterruptedException interEx) {
// Re-interrupt current thread, to allow other threads to react.
Thread.currentThread().interrupt();
}
}
return true;
}
@Test
public void applyBackOff() {
BackOff mock = mock(BackOff.class);
BackOffExecution execution = mock(BackOffExecution.class);
given(execution.nextBackOff()).willReturn(BackOffExecution.STOP);
given(mock.start()).willReturn(execution);
DefaultMessageListenerContainer container = createContainer(mock, createFailingContainerFactory());
container.start();
assertEquals(true, container.isRunning());
container.refreshConnectionUntilSuccessful();
assertEquals(false, container.isRunning());
verify(mock).start();
verify(execution).nextBackOff();
}
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);
}
}
}
private void handleRetry(
final NetworkService service,
final Action action,
final int retries,
final BackOffExecution backOffExecution) {
try {
if (action == Action.register && retries > 0) {
long nextBackoff = backOffExecution.nextBackOff();
LOG.debug("Still {} retries available for {}; waiting for {} ms", retries, service, nextBackoff);
try {
Thread.sleep(nextBackoff);
} catch (InterruptedException e) {
// ignore
}
retry(completionStage(action, service), service, action, retries - 1, backOffExecution);
} else {
LOG.debug("No more retries {} for {}", action, service);
}
} catch (Throwable t) {
LOG.error("Could not continue {} for {}, aborting", action, service, t);
}
}
private void retry(
final CompletionStage<Response> completionStage,
final NetworkService service,
final Action action,
final int retries,
final BackOffExecution backOffExecution) {
completionStage.whenComplete((response, throwable) -> {
if (throwable == null && response.getStatus() < 300) {
LOG.info("{} successfully " + action + "ed", service);
} else {
LOG.error("Could not " + action + " {}", service, throwable);
handleRetry(service, action, retries, backOffExecution);
}
}).exceptionally(throwable -> {
LOG.error("Could not " + action + " {}", service, throwable);
handleRetry(service, action, retries, backOffExecution);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
});
}
@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() {
FixedBackOff backOff = new FixedBackOff();
BackOffExecution execution = backOff.start();
for (int i = 0; i < 100; i++) {
assertEquals(FixedBackOff.DEFAULT_INTERVAL, execution.nextBackOff());
}
}
@Test
public void maxAttemptsReached() {
FixedBackOff backOff = new FixedBackOff(200L, 2);
BackOffExecution execution = backOff.start();
assertEquals(200L, execution.nextBackOff());
assertEquals(200L, execution.nextBackOff());
assertEquals(BackOffExecution.STOP, execution.nextBackOff());
}
@Test
public void startReturnDifferentInstances() {
FixedBackOff backOff = new FixedBackOff(100L, 1);
BackOffExecution execution = backOff.start();
BackOffExecution execution2 = backOff.start();
assertEquals(100L, execution.nextBackOff());
assertEquals(100L, execution2.nextBackOff());
assertEquals(BackOffExecution.STOP, execution.nextBackOff());
assertEquals(BackOffExecution.STOP, execution2.nextBackOff());
}
@Test
public void liveUpdate() {
FixedBackOff backOff = new FixedBackOff(100L, 1);
BackOffExecution execution = backOff.start();
assertEquals(100L, execution.nextBackOff());
backOff.setInterval(200L);
backOff.setMaxAttempts(2);
assertEquals(200L, execution.nextBackOff());
assertEquals(BackOffExecution.STOP, execution.nextBackOff());
}
@Test
public void toStringContent() {
FixedBackOff backOff = new FixedBackOff(200L, 10);
BackOffExecution execution = backOff.start();
assertEquals("FixedBackOff{interval=200, currentAttempts=0, maxAttempts=10}", execution.toString());
execution.nextBackOff();
assertEquals("FixedBackOff{interval=200, currentAttempts=1, maxAttempts=10}", execution.toString());
execution.nextBackOff();
assertEquals("FixedBackOff{interval=200, currentAttempts=2, maxAttempts=10}", 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());
}