I'm reading up on GCM: https://developers.google.com/cloud-messaging/server
and one of the requirements is that the server needs to be able to:
I use Spring RestTemplate for my backend which comes from Spring Boot. There doesn't seem to be a method which I can use to set my retry policy in the docs: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html
Also when I googled, I found the RetryTemplate, but it is part of Spring Batch and doesn't extend RestTemplate which makes me think that it is not supposed to be used for Rest operations, but rather Spring Batch operations like processing large amount of transactions: http://docs.spring.io/spring-batch/2.1.x/apidocs/org/springframework/batch/retry/support/RetryTemplate.html
Is there a way I can use exponential backoff with Spring RestTemplate?
Implementing the Retry Logic. First, you need to enable Spring Retry. You can achieve this by adding the @EnableRetry annotation to your @SpringBootApplication or @Configuration class. You can now use @Retryable to annotate any method to be a candidate or retry and @Recover to specify fallback methods.
Spring Uniform Random Backoff The above logic means that the delay period will be random based on initial delay and maxDelay variables set from the retry configuration that you implement.
Spring Retry provides an ability to automatically re-invoke a failed operation. This is helpful where the errors may be transient (like a momentary network glitch).
I see FixedBackOffPolicy as an implementation of BackOffPolicy that pauses for a fixed period of time before continuing and ExponentialBackOffPolicy as an implementation of BackOffPolicy that increases the back off period for each retry attempt in a given set.
Good day!
I guess, desired behavior could be achived by implementing custom Sleeper class.
Next you need to set this sleeper to BackOffPolicy as follows:
public class RetryTest {
public static final Logger LOG = LoggerFactory.getLogger(RetryTemplate.class);
@org.junit.Test
public void testRT() {
RetryTemplate retryTemplate = new RetryTemplate();
final SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(5);
retryTemplate.setRetryPolicy(retryPolicy);
Sleeper sleeper = new Sleeper() {
private long timeToSleep = 0;
@Override
public void sleep(long timeout) throws InterruptedException {
if (timeToSleep ==0) {
timeToSleep = timeout;
} else {
timeToSleep = (long) (timeToSleep * Math.E);
}
LOG.warn("sleeping for: {}", timeToSleep);
Thread.sleep(timeToSleep);
}
};
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy().withSleeper(sleeper);
retryTemplate.setBackOffPolicy(backOffPolicy);
retryTemplate.execute(new RetryCallback<Void, ResourceAccessException>() {
@Override
public Void doWithRetry(RetryContext retryContext) throws ResourceAccessException {
LOG.debug(">RetryCount: {}", retryContext.getRetryCount());
new RestTemplate().getForObject("https://unreachable.host", String.class);
return null;
}
});
}
}
Also there is ExponentialBackOffPolicy by spring-retry.
Hope this would help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With