Package dev.failsafe

Class 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 via Failsafe.with(Policy, Policy[]) to support policy based execution failure handling, or Failsafe.none() to support execution with no failure handling.

    Async executions are run by default on the ForkJoinPool.commonPool(). Alternative executors can be configured via with(ScheduledExecutorService) and similar methods. All async executions are cancellable and interruptable via the returned CompletableFuture, even those run by a ForkJoinPool or CompletionStage.

    • 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 the innerSupplier 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 asynchronous innerFn 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 the innerSupplier synchronously, handling results according to the configured policies.
      <P extends Policy<R>>
      FailsafeExecutor<R>
      compose​(P innerPolicy)
      Returns a new FailsafeExecutor that composes the currently configured policies around the given innerPolicy.
      <T extends R>
      T
      get​(CheckedSupplier<T> supplier)
      Executes the supplier until a successful result is returned or the configured policies are exceeded.
      <T extends R>
      T
      get​(ContextualSupplier<T,​T> supplier)
      Executes the supplier 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 the supplier 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 the supplier 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 the supplier 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 the supplier 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 the runnable 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 the supplier until a successful result is returned or the configured policies are exceeded.
      FailsafeExecutor<R> onComplete​(EventListener<ExecutionCompletedEvent<R>> listener)
      Registers the listener to be called when an execution is complete.
      FailsafeExecutor<R> onFailure​(EventListener<ExecutionCompletedEvent<R>> listener)
      Registers the listener to be called when an execution fails.
      FailsafeExecutor<R> onSuccess​(EventListener<ExecutionCompletedEvent<R>> listener)
      Registers the listener to be called when an execution is successful.
      void run​(CheckedRunnable runnable)
      Executes the runnable until successful or until the configured policies are exceeded.
      void run​(ContextualRunnable<java.lang.Void> runnable)
      Executes the runnable until successful or until the configured policies are exceeded.
      java.util.concurrent.CompletableFuture<java.lang.Void> runAsync​(CheckedRunnable runnable)
      Executes the runnable asynchronously until successful or until the configured policies are exceeded.
      java.util.concurrent.CompletableFuture<java.lang.Void> runAsync​(ContextualRunnable<java.lang.Void> runnable)
      Executes the runnable 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 the scheduler to use for performing asynchronous executions and listener callbacks.
      FailsafeExecutor<R> with​(java.util.concurrent.Executor executor)
      Configures the executor to use as a wrapper around executions.
      FailsafeExecutor<R> with​(java.util.concurrent.ExecutorService executorService)
      Configures the executorService to use for performing asynchronous executions and listener callbacks.
      FailsafeExecutor<R> with​(java.util.concurrent.ScheduledExecutorService scheduledExecutorService)
      Configures the scheduledExecutorService to use for performing asynchronous executions and listener callbacks.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • executor

        private java.util.concurrent.Executor executor
      • policies

        final java.util.List<? extends Policy<R>> policies
        Policies sorted outermost first
      • completeHandler

        private volatile EventHandler<R> completeHandler
      • failureHandler

        private volatile EventHandler<R> failureHandler
      • successHandler

        private volatile EventHandler<R> successHandler
    • Constructor Detail

      • FailsafeExecutor

        FailsafeExecutor​(java.util.List<? extends Policy<R>> policies)
        Throws:
        java.lang.IllegalArgumentException - if policies is empty
    • 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 new FailsafeExecutor that composes the currently configured policies around the given innerPolicy. For example, consider:

           Failsafe.with(fallback).compose(retryPolicy).compose(circuitBreaker);
         

        This results in the following internal composition when executing a runnable or supplier and handling its result:

           Fallback(RetryPolicy(CircuitBreaker(Supplier)))
         

        This means the CircuitBreaker is first to evaluate the Supplier's result, then the RetryPolicy, then the Fallback. 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 - if innerPolicy is null
        See Also:
        getPolicies()
      • get

        public <T extends R> T get​(CheckedSupplier<T> supplier)
        Executes the supplier until a successful result is returned or the configured policies are exceeded.
        Throws:
        java.lang.NullPointerException - if the supplier is null
        FailsafeException - 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 the supplier until a successful result is returned or the configured policies are exceeded.
        Throws:
        java.lang.NullPointerException - if the supplier is null
        FailsafeException - 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 the runnable until a successful result is returned or the configured policies are exceeded.
        Throws:
        java.lang.NullPointerException - if the runnable is null
      • newCall

        public <T extends RCall<T> newCall​(ContextualSupplier<T,​T> supplier)
        Returns a call that can execute the supplier until a successful result is returned or the configured policies are exceeded.
        Throws:
        java.lang.NullPointerException - if the supplier is null
      • getAsync

        public <T extends R> java.util.concurrent.CompletableFuture<T> getAsync​(CheckedSupplier<T> supplier)
        Executes the supplier asynchronously until a successful result is returned or the configured policies are exceeded.
        Throws:
        java.lang.NullPointerException - if the supplier is null
        java.util.concurrent.RejectedExecutionException - if the supplier cannot be scheduled for execution
      • getAsync

        public <T extends R> java.util.concurrent.CompletableFuture<T> getAsync​(ContextualSupplier<T,​T> supplier)
        Executes the supplier asynchronously until a successful result is returned or the configured policies are exceeded.
        Throws:
        java.lang.NullPointerException - if the supplier is null
        java.util.concurrent.RejectedExecutionException - if the supplier 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 the AsyncExecution.record methods which will trigger failure handling, if needed, by the configured policies, else the resulting CompletableFuture will be completed. Any exception that is thrown from the runnable will automatically be recorded via AsyncExecution.recordException(Throwable).

        Throws:
        java.lang.NullPointerException - if the runnable is null
        java.util.concurrent.RejectedExecutionException - if the runnable 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 the supplier asynchronously until the resulting future is successfully completed or the configured policies are exceeded.

        Cancelling the resulting CompletableFuture will automatically cancels the supplied CompletionStage if it's a Future.

        Throws:
        java.lang.NullPointerException - if the supplier is null
        java.util.concurrent.RejectedExecutionException - if the supplier 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 the supplier asynchronously until the resulting future is successfully completed or the configured policies are exceeded.

        Cancelling the resulting CompletableFuture will automatically cancels the supplied CompletionStage if it's a Future.

        Throws:
        java.lang.NullPointerException - if the supplier is null
        java.util.concurrent.RejectedExecutionException - if the supplier cannot be scheduled for execution
      • run

        public void run​(CheckedRunnable runnable)
        Executes the runnable until successful or until the configured policies are exceeded.
        Throws:
        java.lang.NullPointerException - if the runnable is null
        FailsafeException - 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 the runnable until successful or until the configured policies are exceeded.
        Throws:
        java.lang.NullPointerException - if the runnable is null
        FailsafeException - 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 the runnable asynchronously until successful or until the configured policies are exceeded.
        Throws:
        java.lang.NullPointerException - if the runnable is null
        java.util.concurrent.RejectedExecutionException - if the runnable cannot be scheduled for execution
      • runAsync

        public java.util.concurrent.CompletableFuture<java.lang.Void> runAsync​(ContextualRunnable<java.lang.Void> runnable)
        Executes the runnable asynchronously until successful or until the configured policies are exceeded.
        Throws:
        java.lang.NullPointerException - if the runnable is null
        java.util.concurrent.RejectedExecutionException - if the runnable 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 the AsyncExecution.record methods which will trigger failure handling, if needed, by the configured policies, else the resulting CompletableFuture will be completed. Any exception that is thrown from the runnable will automatically be recorded via AsyncExecution.recordException(Throwable).

        Throws:
        java.lang.NullPointerException - if the runnable is null
        java.util.concurrent.RejectedExecutionException - if the runnable cannot be scheduled for execution
      • onComplete

        public FailsafeExecutor<R> onComplete​(EventListener<ExecutionCompletedEvent<R>> listener)
        Registers the listener 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 the listener 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 a Fallback.

      • onSuccess

        public FailsafeExecutor<R> onSuccess​(EventListener<ExecutionCompletedEvent<R>> listener)
        Registers the listener 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 the onFailure(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 the scheduledExecutorService to use for performing asynchronous executions and listener callbacks.

        Note: The scheduledExecutorService should have a core pool size of at least 2 in order for timeouts to work.

        Throws:
        java.lang.NullPointerException - if scheduledExecutorService is null
        java.lang.IllegalArgumentException - if the scheduledExecutorService has a core pool size of less than 2
      • with

        public FailsafeExecutor<R> with​(java.util.concurrent.ExecutorService executorService)
        Configures the executorService 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 the executorService will be used for actual execution.

        Note: The executorService should have a core pool size or parallelism of at least 2 in order for timeouts to work.

        Throws:
        java.lang.NullPointerException - if executorService is null
      • with

        public FailsafeExecutor<R> with​(java.util.concurrent.Executor executor)
        Configures the executor to use as a wrapper around executions. If the executor is actually an instance of ExecutorService, then the executor will be configured via with(ExecutorService) instead.

        The executor is responsible for propagating executions. Executions that normally return a result, such as get(CheckedSupplier) will return null since the Executor interface does not support results.

        The executor will not be used for getStageAsync calls since those require a returned result.

        Throws:
        java.lang.NullPointerException - if executor is null
      • with

        public FailsafeExecutor<R> with​(Scheduler scheduler)
        Configures the scheduler to use for performing asynchronous executions and listener callbacks.
        Throws:
        java.lang.NullPointerException - if scheduler is null
      • call

        private <T> T call​(ContextualSupplier<T,​T> innerSupplier)
        Calls the innerSupplier synchronously, handling results according to the configured policies.
      • callSync

        private <T> Call<T> callSync​(ContextualSupplier<T,​T> innerSupplier)
        Returns a Call that calls the innerSupplier 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 asynchronous innerFn 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 the innerFn is null
        java.util.concurrent.RejectedExecutionException - if the innerFn cannot be scheduled for execution