@SuppressWarnings("unchecked") protected CompletableFuture<ExecutionResult> onFailureAsync(ExecutionResult result, Scheduler scheduler, FailsafeFuture<Object> future) { if (!policy.isAsync()) return CompletableFuture.completedFuture(onFailure(result)); CompletableFuture<ExecutionResult> promise = new CompletableFuture<>(); Callable<Object> callable = () -> promise.complete(onFailure(result)); try { future.inject((Future) scheduler.schedule(callable, result.getWaitNanos(), TimeUnit.NANOSECONDS)); } catch (Exception e) { promise.completeExceptionally(e); } return promise; } }
@Override protected Supplier<ExecutionResult> supply(Supplier<ExecutionResult> supplier) { return () -> { while (true) { ExecutionResult result = supplier.get(); if (retriesExceeded) return result; result = postExecute(result); if (result.isComplete()) return result; try { Thread.sleep(TimeUnit.NANOSECONDS.toMillis(result.getWaitNanos())); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return ExecutionResult.failure(new FailsafeException(e)); } // Call retry listener if (retryListener != null) retryListener.handle(result, execution); } }; }
/** * Performs post-execution handling of the {@code result}, returning true if complete else false. * * @throws IllegalStateException if the execution is already complete */ synchronized boolean postExecute(ExecutionResult result) { record(result); for (PolicyExecutor<Policy<Object>> policyExecutor : policyExecutors) result = policyExecutor.postExecute(result); waitNanos = result.getWaitNanos(); completed = result.isComplete(); return completed; }