How to wrap a Promise into Promise.retry
Closed this issue · 5 comments
I am using the jersey rx() extension that wraps the requests in CompletionStages. I would like to be able to take this CompletionStage, convert it to a Promise, and use it within a Promises.retry without having to call get().
This means that Promises.retry would accept a Promise, rather than a Callable or Runnable, and then be able to resubmit the original code with binding context for re-execution.
Here is a retry function that I wrote to handle retries that has been adapted to work with Promises.
protected Promise<T> retry(Callable<CompletionStage<T>> callable) throws Exception {
int retries = 0;
boolean isRetry = false;
do {
try {
if (isRetry) {
logger.warn(String.format("Retrying previous request (%s).", retries));
}
return Promises.from(callable.call());
} catch (final Exception e) {
logger.error("An exception was thrown while processing request.", e);
isRetry = true;
if (retries >= maxRetries) {
throw e;
}
}
//
// Back off for two seconds to try and not saturate the server with retry attempts.
//
Thread.sleep(2000);
} while (retries++ < maxRetries);
throw new RuntimeException("The number of maximum retries has been exceeded for this request.");
}
Jeffrey,
If I understand your requirements correctly, then:
- You have
Callable<CompletionStage<T>> callable
that returns a newCompletionStage
whenever it's called. - You should use
net.tascalate.concurrent.Promises.retryFuture(callable, retryPolicy)
- In your case
retryPolicy
is:
RetryPolicy<T> retryPolicy = new RetryPolicy<>(maxRetries, DelayPolicy.fixedInterval(2000L));
Is it what you need?
It looks right. I don't know how I didn't see the retryFuture method before...
How are exceptions handled?
Jeffrey,
Unfortunately, RetryPolicy
class is not documented yet, but you can specify what exceptions are re-tryable and what should stop processing. Please check sources of the class -- but, in general, everything is configurable.
And, btw, in my example above you should use:
RetryPolicy<T> retryPolicy = new RetryPolicy<>(
maxRetries,
DelayPolicy.fixedInterval(2000L).withFirstRetryNoDelay()
);
To avoid waiting before the first execution
This worked. I apologize for not providing a follow up!