public interface RetrySphereClientDecorator extends SphereClient
SphereClient
to handle failures like gateway timeouts and version conflicts through retrying the request.
A best practice example to retry on gateway timeouts and similar problems
public class RetryBadGatewayExample {
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);
}
}
See the test code.
Not best practice but a lot of people requested to retry deletes on version conflicts:
public class RetryDeleteExample {
public static SphereClient ofRetry(final SphereClient delegate) {
final List<RetryRule> retryRules = singletonList(RetryRule.of(isDeleteAndNewVersionIsKnown(), retryWithNewVersion()));
return RetrySphereClientDecorator.of(delegate, retryRules);
}
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;
}
@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);
};
}
}
See the test code.
Modifier and Type | Method and Description |
---|---|
static SphereClient |
of(SphereClient delegate,
List<RetryRule> retryRules) |
static SphereClient of(SphereClient delegate, List<RetryRule> retryRules)