Class FailsafeExecutor<R>
- java.lang.Object
-
- dev.failsafe.FailsafeExecutor<R>
-
- Type Parameters:
R
- result type
public class FailsafeExecutor<R> extends java.lang.Object
An executor that handles failures according to configured
policies
. Can be created viaFailsafe.with(Policy, Policy[])
to support policy based execution failure handling, orFailsafe.none()
to support execution with no failure handling.Async executions are run by default on the
ForkJoinPool.commonPool()
. Alternative executors can be configured viawith(ScheduledExecutorService)
and similar methods. All async executions are cancellable and interruptable via the returned CompletableFuture, even those run by aForkJoinPool
orCompletionStage
.
-
-
Field Summary
Fields Modifier and Type Field Description private EventHandler<R>
completeHandler
(package private) java.util.function.BiConsumer<ExecutionResult<R>,ExecutionContext<R>>
completionHandler
private java.util.concurrent.Executor
executor
private EventHandler<R>
failureHandler
(package private) java.util.List<? extends Policy<R>>
policies
Policies sorted outermost firstprivate Scheduler
scheduler
private EventHandler<R>
successHandler
-
Constructor Summary
Constructors Constructor Description FailsafeExecutor(java.util.List<? extends Policy<R>> policies)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description private <T> T
call(ContextualSupplier<T,T> innerSupplier)
Calls theinnerSupplier
synchronously, handling results according to the configured policies.private <T> java.util.concurrent.CompletableFuture<T>
callAsync(java.util.function.Function<FailsafeFuture<T>,java.util.function.Function<AsyncExecutionInternal<T>,java.util.concurrent.CompletableFuture<ExecutionResult<T>>>> innerFn, boolean asyncExecution)
Calls the asynchronousinnerFn
via the configured Scheduler, handling results according to the configured policies.private <T> Call<T>
callSync(ContextualSupplier<T,T> innerSupplier)
Returns a Call that calls theinnerSupplier
synchronously, handling results according to the configured policies.<P extends Policy<R>>
FailsafeExecutor<R>compose(P innerPolicy)
Returns a newFailsafeExecutor
that composes the currently configured policies around the giveninnerPolicy
.<T extends R>
Tget(CheckedSupplier<T> supplier)
Executes thesupplier
until a successful result is returned or the configured policies are exceeded.<T extends R>
Tget(ContextualSupplier<T,T> supplier)
Executes thesupplier
until a successful result is returned or the configured policies are exceeded.<T extends R>
java.util.concurrent.CompletableFuture<T>getAsync(CheckedSupplier<T> supplier)
Executes thesupplier
asynchronously until a successful result is returned or the configured policies are exceeded.<T extends R>
java.util.concurrent.CompletableFuture<T>getAsync(ContextualSupplier<T,T> supplier)
Executes thesupplier
asynchronously until a successful result is returned or the configured policies are exceeded.<T extends R>
java.util.concurrent.CompletableFuture<T>getAsyncExecution(AsyncRunnable<T> runnable)
This method is intended for integration with asynchronous code.java.util.List<? extends Policy<R>>
getPolicies()
Returns the currently configured policies.<T extends R>
java.util.concurrent.CompletableFuture<T>getStageAsync(CheckedSupplier<? extends java.util.concurrent.CompletionStage<T>> supplier)
Executes thesupplier
asynchronously until the resulting future is successfully completed or the configured policies are exceeded.<T extends R>
java.util.concurrent.CompletableFuture<T>getStageAsync(ContextualSupplier<T,? extends java.util.concurrent.CompletionStage<T>> supplier)
Executes thesupplier
asynchronously until the resulting future is successfully completed or the configured policies are exceeded.Call<java.lang.Void>
newCall(ContextualRunnable<java.lang.Void> runnable)
Returns a call that can execute therunnable
until a successful result is returned or the configured policies are exceeded.<T extends R>
Call<T>newCall(ContextualSupplier<T,T> supplier)
Returns a call that can execute thesupplier
until a successful result is returned or the configured policies are exceeded.FailsafeExecutor<R>
onComplete(EventListener<ExecutionCompletedEvent<R>> listener)
Registers thelistener
to be called when an execution is complete.FailsafeExecutor<R>
onFailure(EventListener<ExecutionCompletedEvent<R>> listener)
Registers thelistener
to be called when an execution fails.FailsafeExecutor<R>
onSuccess(EventListener<ExecutionCompletedEvent<R>> listener)
Registers thelistener
to be called when an execution is successful.void
run(CheckedRunnable runnable)
Executes therunnable
until successful or until the configured policies are exceeded.void
run(ContextualRunnable<java.lang.Void> runnable)
Executes therunnable
until successful or until the configured policies are exceeded.java.util.concurrent.CompletableFuture<java.lang.Void>
runAsync(CheckedRunnable runnable)
Executes therunnable
asynchronously until successful or until the configured policies are exceeded.java.util.concurrent.CompletableFuture<java.lang.Void>
runAsync(ContextualRunnable<java.lang.Void> runnable)
Executes therunnable
asynchronously until successful or until the configured policies are exceeded.java.util.concurrent.CompletableFuture<java.lang.Void>
runAsyncExecution(AsyncRunnable<java.lang.Void> runnable)
This method is intended for integration with asynchronous code.FailsafeExecutor<R>
with(Scheduler scheduler)
Configures thescheduler
to use for performing asynchronous executions and listener callbacks.FailsafeExecutor<R>
with(java.util.concurrent.Executor executor)
Configures theexecutor
to use as a wrapper around executions.FailsafeExecutor<R>
with(java.util.concurrent.ExecutorService executorService)
Configures theexecutorService
to use for performing asynchronous executions and listener callbacks.FailsafeExecutor<R>
with(java.util.concurrent.ScheduledExecutorService scheduledExecutorService)
Configures thescheduledExecutorService
to use for performing asynchronous executions and listener callbacks.
-
-
-
Field Detail
-
scheduler
private Scheduler scheduler
-
executor
private java.util.concurrent.Executor executor
-
completeHandler
private volatile EventHandler<R> completeHandler
-
failureHandler
private volatile EventHandler<R> failureHandler
-
successHandler
private volatile EventHandler<R> successHandler
-
completionHandler
final java.util.function.BiConsumer<ExecutionResult<R>,ExecutionContext<R>> completionHandler
-
-
Method Detail
-
getPolicies
public java.util.List<? extends Policy<R>> getPolicies()
Returns the currently configured policies.- See Also:
compose(Policy)
-
compose
public <P extends Policy<R>> FailsafeExecutor<R> compose(P innerPolicy)
Returns a newFailsafeExecutor
that composes the currently configured policies around the giveninnerPolicy
. For example, consider:Failsafe.with(fallback).compose(retryPolicy).compose(circuitBreaker);
This results in the following internal composition when executing arunnable
orsupplier
and handling its result:Fallback(RetryPolicy(CircuitBreaker(Supplier)))
This means theCircuitBreaker
is first to evaluate theSupplier
's result, then theRetryPolicy
, then theFallback
. Each policy makes its own determination as to whether the result represents a failure. This allows different policies to be used for handling different types of failures.- Throws:
java.lang.NullPointerException
- ifinnerPolicy
is null- See Also:
getPolicies()
-
get
public <T extends R> T get(CheckedSupplier<T> supplier)
Executes thesupplier
until a successful result is returned or the configured policies are exceeded.- Throws:
java.lang.NullPointerException
- if thesupplier
is nullFailsafeException
- if the execution fails with a checked Exception.Throwable.getCause()
can be used to learn the underlying checked exception.
-
get
public <T extends R> T get(ContextualSupplier<T,T> supplier)
Executes thesupplier
until a successful result is returned or the configured policies are exceeded.- Throws:
java.lang.NullPointerException
- if thesupplier
is nullFailsafeException
- if the execution fails with a checked Exception.Throwable.getCause()
can be used to learn the underlying checked exception.
-
newCall
public Call<java.lang.Void> newCall(ContextualRunnable<java.lang.Void> runnable)
Returns a call that can execute therunnable
until a successful result is returned or the configured policies are exceeded.- Throws:
java.lang.NullPointerException
- if therunnable
is null
-
newCall
public <T extends R> Call<T> newCall(ContextualSupplier<T,T> supplier)
Returns a call that can execute thesupplier
until a successful result is returned or the configured policies are exceeded.- Throws:
java.lang.NullPointerException
- if thesupplier
is null
-
getAsync
public <T extends R> java.util.concurrent.CompletableFuture<T> getAsync(CheckedSupplier<T> supplier)
Executes thesupplier
asynchronously until a successful result is returned or the configured policies are exceeded.- Throws:
java.lang.NullPointerException
- if thesupplier
is nulljava.util.concurrent.RejectedExecutionException
- if thesupplier
cannot be scheduled for execution
-
getAsync
public <T extends R> java.util.concurrent.CompletableFuture<T> getAsync(ContextualSupplier<T,T> supplier)
Executes thesupplier
asynchronously until a successful result is returned or the configured policies are exceeded.- Throws:
java.lang.NullPointerException
- if thesupplier
is nulljava.util.concurrent.RejectedExecutionException
- if thesupplier
cannot be scheduled for execution
-
getAsyncExecution
public <T extends R> java.util.concurrent.CompletableFuture<T> getAsyncExecution(AsyncRunnable<T> runnable)
This method is intended for integration with asynchronous code.Executes the
runnable
asynchronously until a successful result is recorded or the configured policies are exceeded. Executions must be recorded via one of theAsyncExecution.record
methods which will trigger failure handling, if needed, by the configured policies, else the resultingCompletableFuture
will be completed. Any exception that is thrown from therunnable
will automatically be recorded viaAsyncExecution.recordException(Throwable)
.- Throws:
java.lang.NullPointerException
- if therunnable
is nulljava.util.concurrent.RejectedExecutionException
- if therunnable
cannot be scheduled for execution
-
getStageAsync
public <T extends R> java.util.concurrent.CompletableFuture<T> getStageAsync(CheckedSupplier<? extends java.util.concurrent.CompletionStage<T>> supplier)
Executes thesupplier
asynchronously until the resulting future is successfully completed or the configured policies are exceeded.Cancelling the resulting
CompletableFuture
will automatically cancels the suppliedCompletionStage
if it's aFuture
.- Throws:
java.lang.NullPointerException
- if thesupplier
is nulljava.util.concurrent.RejectedExecutionException
- if thesupplier
cannot be scheduled for execution
-
getStageAsync
public <T extends R> java.util.concurrent.CompletableFuture<T> getStageAsync(ContextualSupplier<T,? extends java.util.concurrent.CompletionStage<T>> supplier)
Executes thesupplier
asynchronously until the resulting future is successfully completed or the configured policies are exceeded.Cancelling the resulting
CompletableFuture
will automatically cancels the suppliedCompletionStage
if it's aFuture
.- Throws:
java.lang.NullPointerException
- if thesupplier
is nulljava.util.concurrent.RejectedExecutionException
- if thesupplier
cannot be scheduled for execution
-
run
public void run(CheckedRunnable runnable)
Executes therunnable
until successful or until the configured policies are exceeded.- Throws:
java.lang.NullPointerException
- if therunnable
is nullFailsafeException
- if the execution fails with a checked Exception.Throwable.getCause()
can be used to learn the underlying checked exception.
-
run
public void run(ContextualRunnable<java.lang.Void> runnable)
Executes therunnable
until successful or until the configured policies are exceeded.- Throws:
java.lang.NullPointerException
- if therunnable
is nullFailsafeException
- if the execution fails with a checked Exception.Throwable.getCause()
can be used to learn the underlying checked exception.
-
runAsync
public java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(CheckedRunnable runnable)
Executes therunnable
asynchronously until successful or until the configured policies are exceeded.- Throws:
java.lang.NullPointerException
- if therunnable
is nulljava.util.concurrent.RejectedExecutionException
- if therunnable
cannot be scheduled for execution
-
runAsync
public java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(ContextualRunnable<java.lang.Void> runnable)
Executes therunnable
asynchronously until successful or until the configured policies are exceeded.- Throws:
java.lang.NullPointerException
- if therunnable
is nulljava.util.concurrent.RejectedExecutionException
- if therunnable
cannot be scheduled for execution
-
runAsyncExecution
public java.util.concurrent.CompletableFuture<java.lang.Void> runAsyncExecution(AsyncRunnable<java.lang.Void> runnable)
This method is intended for integration with asynchronous code.Executes the
runnable
asynchronously until a successful result is recorded or the configured policies are exceeded. Executions must be recorded via one of theAsyncExecution.record
methods which will trigger failure handling, if needed, by the configured policies, else the resultingCompletableFuture
will be completed. Any exception that is thrown from therunnable
will automatically be recorded viaAsyncExecution.recordException(Throwable)
.- Throws:
java.lang.NullPointerException
- if therunnable
is nulljava.util.concurrent.RejectedExecutionException
- if therunnable
cannot be scheduled for execution
-
onComplete
public FailsafeExecutor<R> onComplete(EventListener<ExecutionCompletedEvent<R>> listener)
Registers thelistener
to be called when an execution is complete. This occurs when an execution is successful according to all policies, or all policies have been exceeded.Note: Any exceptions that are thrown from within the
listener
are ignored.
-
onFailure
public FailsafeExecutor<R> onFailure(EventListener<ExecutionCompletedEvent<R>> listener)
Registers thelistener
to be called when an execution fails. This occurs when the execution fails according to some policy, and all policies have been exceeded.Note: Any exceptions that are thrown from within the
listener
are ignored. To provide an alternative result for a failed execution, use aFallback
.
-
onSuccess
public FailsafeExecutor<R> onSuccess(EventListener<ExecutionCompletedEvent<R>> listener)
Registers thelistener
to be called when an execution is successful. If multiple policies, are configured, this handler is called when execution is complete and all policies succeed. If all policies do not succeed, then theonFailure(EventListener)
registered listener is called instead.Note: Any exceptions that are thrown from within the
listener
are ignored.
-
with
public FailsafeExecutor<R> with(java.util.concurrent.ScheduledExecutorService scheduledExecutorService)
Configures thescheduledExecutorService
to use for performing asynchronous executions and listener callbacks.Note: The
scheduledExecutorService
should have a core pool size of at least 2 in order fortimeouts
to work.- Throws:
java.lang.NullPointerException
- ifscheduledExecutorService
is nulljava.lang.IllegalArgumentException
- if thescheduledExecutorService
has a core pool size of less than 2
-
with
public FailsafeExecutor<R> with(java.util.concurrent.ExecutorService executorService)
Configures theexecutorService
to use for performing asynchronous executions and listener callbacks. For async executions that require a delay, an internal ScheduledExecutorService will be used for the delay, then theexecutorService
will be used for actual execution.Note: The
executorService
should have a core pool size or parallelism of at least 2 in order fortimeouts
to work.- Throws:
java.lang.NullPointerException
- ifexecutorService
is null
-
with
public FailsafeExecutor<R> with(java.util.concurrent.Executor executor)
Configures theexecutor
to use as a wrapper around executions. If theexecutor
is actually an instance ofExecutorService
, then theexecutor
will be configured viawith(ExecutorService)
instead.The
executor
is responsible for propagating executions. Executions that normally return a result, such asget(CheckedSupplier)
will returnnull
since theExecutor
interface does not support results.The
executor
will not be used forgetStageAsync
calls since those require a returned result.- Throws:
java.lang.NullPointerException
- ifexecutor
is null
-
with
public FailsafeExecutor<R> with(Scheduler scheduler)
Configures thescheduler
to use for performing asynchronous executions and listener callbacks.- Throws:
java.lang.NullPointerException
- ifscheduler
is null
-
call
private <T> T call(ContextualSupplier<T,T> innerSupplier)
Calls theinnerSupplier
synchronously, handling results according to the configured policies.
-
callSync
private <T> Call<T> callSync(ContextualSupplier<T,T> innerSupplier)
Returns a Call that calls theinnerSupplier
synchronously, handling results according to the configured policies.
-
callAsync
private <T> java.util.concurrent.CompletableFuture<T> callAsync(java.util.function.Function<FailsafeFuture<T>,java.util.function.Function<AsyncExecutionInternal<T>,java.util.concurrent.CompletableFuture<ExecutionResult<T>>>> innerFn, boolean asyncExecution)
Calls the asynchronousinnerFn
via the configured Scheduler, handling results according to the configured policies.- Parameters:
asyncExecution
- whether this is a detached, async execution that must be manually completed- Throws:
java.lang.NullPointerException
- if theinnerFn
is nulljava.util.concurrent.RejectedExecutionException
- if theinnerFn
cannot be scheduled for execution
-
-