private static <V> V run( Callable<V> callable, TimedRetryAlgorithm timedAlgorithm, ResultRetryAlgorithm<V> resultAlgorithm) throws ExecutionException, InterruptedException { RetryAlgorithm<V> retryAlgorithm = new RetryAlgorithm<>(resultAlgorithm, timedAlgorithm); RetryingExecutor<V> executor = new DirectRetryingExecutor<>(retryAlgorithm); RetryingFuture<V> retryingFuture = executor.createFuture(callable); executor.submit(retryingFuture); return retryingFuture.get(); }
/** * Creates a {@link RetryingFuture}, which is a facade, returned to the client code to wait for * any retriable operation to complete. The future is bounded to {@code this} executor instance. * * @param callable the actual callable, which should be executed in a retriable context * @return retrying future facade */ @Override public RetryingFuture<ResponseT> createFuture(Callable<ResponseT> callable) { return createFuture(callable, NoopRetryingContext.create()); }
/** * Submits an attempt for execution in the current thread, causing the current thread to sleep for * the specified by the {@link RetryingFuture#getAttemptSettings()} amount of time. As result, * this method completes execution only after the specified {@code retryingFuture} completes. * * @param retryingFuture the future previously returned by {@link #createFuture(Callable, * RetryingContext)} * @return returns completed {@code retryingFuture} */ @Override public ApiFuture<ResponseT> submit(RetryingFuture<ResponseT> retryingFuture) { while (!retryingFuture.isDone()) { try { sleep(retryingFuture.getAttemptSettings().getRandomizedRetryDelay()); ResponseT response = retryingFuture.getCallable().call(); retryingFuture.setAttemptFuture(ApiFutures.immediateFuture(response)); } catch (InterruptedException | InterruptedIOException | ClosedByInterruptException e) { Thread.currentThread().interrupt(); retryingFuture.setAttemptFuture(ApiFutures.<ResponseT>immediateFailedFuture(e)); } catch (Exception e) { retryingFuture.setAttemptFuture(ApiFutures.<ResponseT>immediateFailedFuture(e)); } } return retryingFuture; }
/** * Creates a {@link RetryingFuture}, which is a facade, returned to the client code to wait for * any retriable operation to complete. The future is bounded to {@code this} executor instance. * * @param callable the actual callable, which should be executed in a retriable context * @return retrying future facade */ @Override public RetryingFuture<ResponseT> createFuture(Callable<ResponseT> callable) { return createFuture(callable, NoopRetryingContext.create()); }
/** * Submits an attempt for execution in the current thread, causing the current thread to sleep for * the specified by the {@link RetryingFuture#getAttemptSettings()} amount of time. As result, * this method completes execution only after the specified {@code retryingFuture} completes. * * @param retryingFuture the future previously returned by {@link #createFuture(Callable, * RetryingContext)} * @return returns completed {@code retryingFuture} */ @Override public ApiFuture<ResponseT> submit(RetryingFuture<ResponseT> retryingFuture) { while (!retryingFuture.isDone()) { try { sleep(retryingFuture.getAttemptSettings().getRandomizedRetryDelay()); ResponseT response = retryingFuture.getCallable().call(); retryingFuture.setAttemptFuture(ApiFutures.immediateFuture(response)); } catch (InterruptedException | InterruptedIOException | ClosedByInterruptException e) { Thread.currentThread().interrupt(); retryingFuture.setAttemptFuture(ApiFutures.<ResponseT>immediateFailedFuture(e)); } catch (Exception e) { retryingFuture.setAttemptFuture(ApiFutures.<ResponseT>immediateFailedFuture(e)); } } return retryingFuture; }
@Override protected RetryingExecutorWithContext<String> getExecutor(RetryAlgorithm<String> retryAlgorithm) { return new DirectRetryingExecutor<>(retryAlgorithm); }
private static <V> V run( Callable<V> callable, TimedRetryAlgorithm timedAlgorithm, ResultRetryAlgorithm<V> resultAlgorithm) throws ExecutionException, InterruptedException { RetryAlgorithm<V> retryAlgorithm = new RetryAlgorithm<>(resultAlgorithm, timedAlgorithm); RetryingExecutor<V> executor = new DirectRetryingExecutor<>(retryAlgorithm); RetryingFuture<V> retryingFuture = executor.createFuture(callable); executor.submit(retryingFuture); return retryingFuture.get(); }