/** * 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 */ @BetaApi("The surface for passing per operation state is not yet stable") @Override public RetryingFuture<ResponseT> createFuture( Callable<ResponseT> callable, RetryingContext context) { return new BasicRetryingFuture<>(callable, retryAlgorithm, context); }
@Override public boolean cancel(boolean mayInterruptIfRunning) { synchronized (lock) { if (attemptFutureCompletionListener == null) { // explicit retry future cancellation, most probably even before the first attempt started return super.cancel(mayInterruptIfRunning); } // will result in attempt triggered cancellation of the whole future via callback chain attemptFutureCompletionListener.attemptFuture.cancel(mayInterruptIfRunning); return isCancelled(); } }
@Override public void setAttemptFuture(ApiFuture<ResponseT> attemptFuture) { try { if (isDone()) { return; } ResponseT response = attemptFuture.get(); handleAttempt(null, response); } catch (ExecutionException e) { handleAttempt(e.getCause(), null); } catch (Throwable e) { handleAttempt(e, null); } }
clearAttemptServiceData(); if (throwable instanceof CancellationException) { super.setException(throwable); if (isDone()) { return; tracer.attemptFailed(throwable, nextAttemptSettings.getRandomizedRetryDelay()); attemptSettings = nextAttemptSettings; setAttemptResult(throwable, response, true);
clearAttemptServiceData(); if (throwable instanceof CancellationException) { super.setException(throwable); if (isDone()) { return; tracer.attemptFailed(throwable, nextAttemptSettings.getRandomizedRetryDelay()); attemptSettings = nextAttemptSettings; setAttemptResult(throwable, response, true);
@Override public void setAttemptFuture(ApiFuture<ResponseT> attemptFuture) { try { if (isDone()) { return; } ResponseT response = attemptFuture.get(); handleAttempt(null, response); } catch (ExecutionException e) { handleAttempt(e.getCause(), null); } catch (Throwable e) { handleAttempt(e, null); } }
@Override public boolean cancel(boolean mayInterruptIfRunning) { synchronized (lock) { if (attemptFutureCompletionListener == null) { // explicit retry future cancellation, most probably even before the first attempt started return super.cancel(mayInterruptIfRunning); } // will result in attempt triggered cancellation of the whole future via callback chain attemptFutureCompletionListener.attemptFuture.cancel(mayInterruptIfRunning); return isCancelled(); } }
/** * 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 */ @BetaApi("The surface for passing per operation state is not yet stable") @Override public RetryingFuture<ResponseT> createFuture( Callable<ResponseT> callable, RetryingContext context) { return new BasicRetryingFuture<>(callable, retryAlgorithm, context); }