public static AsyncRetrier create(ScheduledExecutorService sleeper) { return new AsyncRetrier(sleeper); }
public <T> ListenableFuture<T> retry(final Supplier<ListenableFuture<T>> code, final int retries, final long delayMillis) { return retry(code, retries, delayMillis, MILLISECONDS, Predicates.<T>alwaysTrue()); }
/** * Retry {@code code} up to {@code retries} times. */ public <T> ListenableFuture<T> retry(final Supplier<ListenableFuture<T>> code, final int retries, final long delay, final TimeUnit timeUnit, final Predicate<T> retryCondition) { SettableFuture<T> future = SettableFuture.create(); startRetry(future, code, retries, delay, timeUnit, retryCondition); return future; }
private <T> void startRetry(final SettableFuture<T> future, final Supplier<ListenableFuture<T>> code, final int retries, final long delay, final TimeUnit timeUnit, final Predicate<T> retryCondition) { ListenableFuture<T> codeFuture; try { codeFuture = code.get(); } catch (Exception e) { handleFailure(future, code, retries, delay, timeUnit, retryCondition, e); return; } Futures.addCallback(codeFuture, new FutureCallback<T>() { @Override public void onSuccess(T result) { if (retryCondition.apply(result)) { future.set(result); } else { RuntimeException exception = new RuntimeException("Failed retry condition"); handleFailure(future, code, retries, delay, timeUnit, retryCondition, exception); } } @Override public void onFailure(Throwable t) { handleFailure(future, code, retries, delay, timeUnit, retryCondition, t); } }, MoreExecutors.directExecutor()); }
private <T> void handleFailure(final SettableFuture<T> future, final Supplier<ListenableFuture<T>> code, final int retries, final long delay, final TimeUnit timeUnit, final Predicate<T> retryCondition, Throwable t) { if (retries > 0) { executorService.schedule( () -> startRetry(future, code, retries - 1, delay, timeUnit, retryCondition), delay, timeUnit); } else { future.setException(t); } } }
public <T> ListenableFuture<T> retry(final Supplier<ListenableFuture<T>> code, final int retries, final long delay, final TimeUnit timeUnit) { return retry(code, retries, delay, timeUnit, Predicates.<T>alwaysTrue()); }