@Override public RetryStrategy apply(final RetryContext retryOperationContext) { if (retryOperationContext.getAttempt() > maxAttempts) { return RetryStrategy.resume(retryOperationContext.getLatestError()); } else { final Object parameterObject = retryOperationContext.getLatestParameter(); return RetryStrategy.retryImmediately(parameterObject); } }
@Override public RetryStrategy apply(final RetryContext retryOperationContext) { return RetryStrategy.stop(retryOperationContext.getFirstError()); }
private List<RetryRule> createRules() { final Predicate<RetryContext> isFatal = r -> { final Throwable latestError = r.getLatestError(); final boolean unknownHost = latestError instanceof HttpException && latestError != null && latestError instanceof UnknownHostException; final boolean unauthorized = latestError instanceof UnauthorizedException; return unknownHost || unauthorized; }; final RetryRule fatalRetryRule = RetryRule.of(isFatal, RetryAction.ofShutdownServiceAndSendLatestException()); final RetryRule retryScheduledRetryRule = RetryRule.of(RetryPredicate.ofAlwaysTrue(), RetryAction.ofScheduledRetry(2, retryContext -> Duration.ofMillis(retryContext.getAttempt() * retryContext.getAttempt() * 50))); return asList(fatalRetryRule, retryScheduledRetryRule); }
private static Predicate<RetryContext> isDeleteAndNewVersionIsKnown() { return retryContext -> retryContext.getLatestError() instanceof ConcurrentModificationException && ((ConcurrentModificationException) retryContext.getLatestError()).getCurrentVersion() != null && retryContext.getLatestParameter() instanceof SphereRequest && ((SphereRequest) retryContext.getLatestParameter()).httpRequestIntent().getHttpMethod() == HttpMethod.DELETE; }
/** * Creates a predicate which will be true if the latest error is a subclass of {@code errorClass}. * * @param errorClass error class to match * @return predicate */ static RetryPredicate ofMatchingErrors(final Class<? extends Throwable> errorClass) { return retryContext -> errorClass.isAssignableFrom(retryContext.getLatestError().getClass()); }
public static SphereClient ofRetry(final SphereClient delegate) { final int maxAttempts = 5; final List<RetryRule> retryRules = singletonList(RetryRule.of( RetryPredicate.ofMatchingStatusCodes(BAD_GATEWAY_502, SERVICE_UNAVAILABLE_503, GATEWAY_TIMEOUT_504), RetryAction.ofScheduledRetry(maxAttempts, context -> Duration.ofSeconds(context.getAttempt() * 2))) ); return RetrySphereClientDecorator.of(delegate, retryRules); } }
@SuppressWarnings("unchecked") private static RetryAction retryWithNewVersion() { return (RetryContext c) -> { final SphereRequest sphereRequest = (SphereRequest) c.getLatestParameter(); final Object newParameter = new SphereRequestDecorator(sphereRequest) { @Override public HttpRequestIntent httpRequestIntent() { final HttpRequestIntent original = super.httpRequestIntent(); final Long currentVersion = ((ConcurrentModificationException) c.getLatestError()).getCurrentVersion(); final String path = original.getPath().replaceAll("\\bversion=\\d+", "version=" + currentVersion); return original.withPath(path); } }; return RetryStrategy.retryImmediately(newParameter); }; } }
private List<RetryRule> createRules() { final Predicate<RetryContext> isFatal = r -> { final Throwable latestError = r.getLatestError(); final boolean unknownHost = latestError instanceof HttpException && latestError != null && latestError instanceof UnknownHostException; final boolean unauthorized = latestError instanceof UnauthorizedException; return unknownHost || unauthorized; }; final RetryRule fatalRetryRule = RetryRule.of(isFatal, RetryAction.ofShutdownServiceAndSendLatestException()); final RetryRule retryScheduledRetryRule = RetryRule.of(RetryPredicate.ofAlwaysTrue(), RetryAction.ofScheduledRetry(2, retryContext -> Duration.ofMillis(retryContext.getAttempt() * retryContext.getAttempt() * 50))); return asList(fatalRetryRule, retryScheduledRetryRule); }
/** * Creates a predicate which matches another predicate for status codes for {@link SphereServiceException}s. * * @param predicate predicate which tests if a status code should match the {@link RetryPredicate} * @return predicate */ static RetryPredicate ofMatchingStatusCodes(final Predicate<Integer> predicate) { return retryContext -> retryContext.getLatestError() instanceof SphereServiceException && predicate.test(((SphereServiceException) retryContext.getLatestError()).getStatusCode()); } }
@Test public void scheduledRetry() throws Exception { try (final Service service = new Failing2TimesServiceImpl()) { final RetryAction op = RetryAction.ofScheduledRetry(3, o -> Duration.ofMillis(o.getAttempt() * 100)); final List<RetryRule> retryRules = singletonList(RetryRule.of(RetryPredicate.ofAlwaysTrue(), op)); try(final AsyncRetrySupervisor supervisor = AsyncRetrySupervisor.of(retryRules)) { final CompletionStage<Integer> bar = supervisor.supervise(service, service::apply, "bar"); assertThat(waitAndGet(bar)).isEqualTo(3); assertThat(service.isClosed()).isFalse(); } } }
@Override public RetryStrategy apply(final RetryContext retryOperationContext) { if (retryOperationContext.getAttempt() > maxAttempts) { return RetryStrategy.resume(retryOperationContext.getLatestError()); } else { final Duration duration = durationFunction.apply(retryOperationContext); final Object parameterObject = retryOperationContext.getLatestParameter(); return RetryStrategy.retryScheduled(parameterObject, duration); } }
@Override public RetryStrategy apply(final RetryContext retryOperationContext) { return RetryStrategy.resume(retryOperationContext.getLatestError()); }
@Override public RetryStrategy apply(final RetryContext retryOperationContext) { return RetryStrategy.resume(retryOperationContext.getFirstError()); }
@Override public RetryStrategy apply(final RetryContext retryOperationContext) { return RetryStrategy.stop(retryOperationContext.getLatestError()); }