/** * Executes the {@code supplier} asynchronously until a successful result is returned or the configured policies are * exceeded. This method is intended for integration with asynchronous code. Retries must be manually scheduled via * one of the {@code AsyncExecution.retry} methods. * <p> * If a configured circuit breaker is open, the resulting future is completed with {@link * CircuitBreakerOpenException}. * * @throws NullPointerException if the {@code supplier} is null * @throws RejectedExecutionException if the {@code supplier} cannot be scheduled for execution */ public <T extends R> CompletableFuture<T> getAsyncExecution(AsyncSupplier<T> supplier) { return callAsync(execution -> Functions.asyncOfExecution(supplier, execution), true); }
/** * Executes the {@code supplier} asynchronously until the resulting future is successfully completed or the configured * policies are exceeded. This method is intended for integration with asynchronous code. Retries must be manually * scheduled via one of the {@code AsyncExecution.retry} methods. * <p> * If a configured circuit breaker is open, the resulting future is completed exceptionally with {@link * CircuitBreakerOpenException}. * * @throws NullPointerException if the {@code supplier} is null * @throws RejectedExecutionException if the {@code supplier} cannot be scheduled for execution */ public <T extends R> CompletableFuture<T> getStageAsyncExecution( AsyncSupplier<? extends CompletionStage<T>> supplier) { return callAsync(execution -> Functions.asyncOfFutureExecution(supplier, execution), true); }
/** * Executes the {@code runnable} asynchronously until successful or until the configured policies are exceeded. * <p> * If a configured circuit breaker is open, the resulting future is completed with {@link * CircuitBreakerOpenException}. * * @throws NullPointerException if the {@code runnable} is null * @throws RejectedExecutionException if the {@code runnable} cannot be scheduled for execution */ public CompletableFuture<Void> runAsync(CheckedRunnable runnable) { return callAsync(execution -> Functions.promiseOf(runnable, execution), false); }
/** * Configures the {@code fallback} to be executed if execution fails. * * @throws NullPointerException if {@code fallback} is null */ public static <R> Fallback<R> of(CheckedRunnable fallback) { return new Fallback<>(Functions.fnOf(Assert.notNull(fallback, "fallback")), false); }
/** * Executes the {@code supplier} until a successful result is returned or the configured policies are exceeded. * * @throws NullPointerException if the {@code supplier} is null * @throws FailsafeException if the {@code supplier} fails with a checked Exception or if interrupted while * waiting to perform a retry. * @throws CircuitBreakerOpenException if a configured circuit is open. */ public <T extends R> T get(ContextualSupplier<T> supplier) { return call(execution -> Functions.supplierOf(supplier, execution)); }
/** * Executes the {@code supplier} asynchronously until the resulting future is successfully completed or the configured * policies are exceeded. * <p> * If a configured circuit breaker is open, the resulting future is completed exceptionally with {@link * CircuitBreakerOpenException}. * * @throws NullPointerException if the {@code supplier} is null * @throws RejectedExecutionException if the {@code supplier} cannot be scheduled for execution */ public <T extends R> CompletableFuture<T> getStageAsync(CheckedSupplier<? extends CompletionStage<T>> supplier) { return callAsync(execution -> Functions.promiseOfStage(supplier, execution), false); }
void inject(Supplier<CompletableFuture<ExecutionResult>> supplier, boolean asyncExecution) { if (!asyncExecution) { outerExecutionSupplier = supplier; } else { outerExecutionSupplier = innerExecutionSupplier = Functions.settableSupplierOf(supplier); } for (PolicyExecutor<Policy<Object>> policyExecutor : policyExecutors) outerExecutionSupplier = policyExecutor.supplyAsync(outerExecutionSupplier, scheduler, this.future); }
/** * Performs an asynchronous execution. * * @param asyncExecution whether this is a detached, async execution that must be manually completed */ @SuppressWarnings("unchecked") void executeAsync(boolean asyncExecution) { if (!asyncExecution) Functions.makeAsync(outerExecutionSupplier, scheduler, future).get().whenComplete(this::complete); else future.inject((Future) scheduler.schedule(innerExecutionSupplier::get, 0, TimeUnit.NANOSECONDS)); }
/** * Calls the {@code supplier} synchronously, handling results according to the configured policies. * * @throws FailsafeException if the {@code supplier} fails with a checked Exception or if interrupted while * waiting to perform a retry. * @throws CircuitBreakerOpenException if a configured circuit breaker is open */ @SuppressWarnings("unchecked") private <T> T call(Function<Execution, CheckedSupplier<?>> supplierFn) { Execution execution = new Execution(this); Supplier<ExecutionResult> supplier = Functions.resultSupplierOf(supplierFn.apply(execution), execution); ExecutionResult result = execution.executeSync(supplier); if (result.getFailure() != null) throw result.getFailure() instanceof RuntimeException ? (RuntimeException) result.getFailure() : new FailsafeException(result.getFailure()); return (T) result.getResult(); }
/** * Configures the {@code fallback} to be executed if execution fails. The {@code fallback} accepts an {@link * ExecutionAttemptedEvent}. * * @throws NullPointerException if {@code fallback} is null */ @SuppressWarnings("unchecked") public static <R> Fallback<R> of(CheckedConsumer<ExecutionAttemptedEvent<? extends R>> fallback) { return new Fallback<>(Functions.fnOf(Assert.notNull((CheckedConsumer) fallback, "fallback")), false); }
/** * Executes the {@code runnable} until successful or until the configured policies are exceeded. * * @throws NullPointerException if the {@code runnable} is null * @throws FailsafeException if the {@code runnable} fails with a checked Exception or if interrupted while * waiting to perform a retry. * @throws CircuitBreakerOpenException if a configured circuit is open. */ public void run(ContextualRunnable runnable) { call(execution -> Functions.supplierOf(runnable, execution)); }
/** * Executes the {@code supplier} asynchronously until the resulting future is successfully completed or the configured * policies are exceeded. * <p> * If a configured circuit breaker is open, the resulting future is completed exceptionally with {@link * CircuitBreakerOpenException}. * * @throws NullPointerException if the {@code supplier} is null * @throws RejectedExecutionException if the {@code supplier} cannot be scheduled for execution */ public <T extends R> CompletableFuture<T> getStageAsync(ContextualSupplier<? extends CompletionStage<T>> supplier) { return callAsync(execution -> Functions.promiseOfStage(supplier, execution), false); }
/** * Configures the {@code fallback} to be executed if execution fails. * * @throws NullPointerException if {@code fallback} is null */ @SuppressWarnings("unchecked") public static <R> Fallback<R> of(CheckedSupplier<? extends R> fallback) { return new Fallback<>(Functions.fnOf((CheckedSupplier<R>) Assert.notNull(fallback, "fallback")), false); }
/** * Executes the {@code runnable} asynchronously until successful or until the configured policies are exceeded. * <p> * If a configured circuit breaker is open, the resulting future is completed with {@link * CircuitBreakerOpenException}. * * @throws NullPointerException if the {@code runnable} is null * @throws RejectedExecutionException if the {@code runnable} cannot be scheduled for execution */ public CompletableFuture<Void> runAsync(ContextualRunnable runnable) { return callAsync(execution -> Functions.promiseOf(runnable, execution), false); }
/** * Executes the {@code runnable} until successful or until the configured policies are exceeded. * * @throws NullPointerException if the {@code runnable} is null * @throws FailsafeException if the {@code supplier} fails with a checked Exception or if interrupted while * waiting to perform a retry. * @throws CircuitBreakerOpenException if a configured circuit is open. */ public void run(CheckedRunnable runnable) { call(execution -> Functions.supplierOf(runnable)); }
/** * Executes the {@code runnable} asynchronously until successful or until the configured policies are exceeded. This * method is intended for integration with asynchronous code. Retries must be manually scheduled via one of the {@code * AsyncExecution.retry} methods. * <p> * If a configured circuit breaker is open, the resulting future is completed with {@link * CircuitBreakerOpenException}. * * @throws NullPointerException if the {@code runnable} is null * @throws RejectedExecutionException if the {@code runnable} cannot be scheduled for execution */ public CompletableFuture<Void> runAsyncExecution(AsyncRunnable runnable) { return callAsync(execution -> Functions.asyncOfExecution(runnable, execution), true); }
/** * Configures the {@code fallback} result to be returned if execution fails. * * @throws NullPointerException if {@code fallback} is null */ @SuppressWarnings("rawtypes") public static <R> Fallback<R> of(R fallback) { return new Fallback<>(Functions.fnOf(Assert.notNull(fallback, "fallback")), false); }
/** * Executes the {@code supplier} asynchronously until a successful result is returned or the configured policies are * exceeded. * <p> * If a configured circuit breaker is open, the resulting future is completed with {@link * CircuitBreakerOpenException}. * * @throws NullPointerException if the {@code supplier} is null * @throws RejectedExecutionException if the {@code supplier} cannot be scheduled for execution */ public <T extends R> CompletableFuture<T> getAsync(CheckedSupplier<T> supplier) { return callAsync(execution -> Functions.promiseOf(supplier, execution), false); }
/** * Configures the {@code fallback} to be executed asynchronously if execution fails. * * @throws NullPointerException if {@code fallback} is null */ public static <R> Fallback<R> ofAsync(CheckedRunnable fallback) { return new Fallback<>(Functions.fnOf(Assert.notNull(fallback, "fallback")), true); }
/** * Executes the {@code supplier} asynchronously until a successful result is returned or the configured policies are * exceeded. * <p> * If a configured circuit breaker is open, the resulting future is completed with {@link * CircuitBreakerOpenException}. * * @throws NullPointerException if the {@code supplier} is null * @throws RejectedExecutionException if the {@code supplier} cannot be scheduled for execution */ public <T extends R> CompletableFuture<T> getAsync(ContextualSupplier<T> supplier) { return callAsync(execution -> Functions.promiseOf(supplier, execution), false); }