failsafe v3.0 Release Notes

  • API Changes

    ๐Ÿš€ This release introduces some breaking changes to the API:


    • โšก๏ธ The maven group id for Failsafe has changed to dev.failsafe. Be sure to update your build config.
    • โšก๏ธ All files have been moved to the dev.failsafe package. Be sure to update your imports.


    • ๐Ÿ— All policies now use a builder API. Using the builder API mostly requires inserting builder() and build() methods into the call chain for constructing a policy since the actual with configuration methods are mostly the same as in 2.x policies, with a few changes described below. Some notes:
      • A policy builder can be created via builder(), ex: RetryPolicy.builder().
      • RetryPolicy and CircuitBreaker can also be constructed with default values using ofDefaults().
      • Fallback and Timeout offer additional factory methods for creating a a policy with only their required arguments, without using a builder, ex: Timeout.of(Duration.ofSeconds(10)). Optional arguments must be specified through a builder, ex: Timeout.builder(duration).withInterrupt().build().
      • Policy configuration is now accessible via a policy.getConfig().

    RetryPolicy and CircuitBreaker

    • In RetryPolicyBuilder and CircuitBreakerBuilder:
      • withDelay has been renamed to withDelayFn.
      • withDelayOn has been renamed to withDelayFnOn.
      • withDelayWhen has been renamed to withDelayFnWhen.
      • The above method signatures have also been changed to accept a ContextualSupplier instead of a DelayFunction, since it provides access to the same information.


    • onOpen, onClose, and onHalfOpen methods now accept a CircuitBreakerStateChangedEvent argument.
    • ๐Ÿšš allowsExecution() was removed in favor of acquirePermit() and tryAcquirePermit(), which are meant for standalone CircuitBreaker usage.


    • ๐Ÿšš The Fallback async factory methods have been removed in favor of a FallbackBuilder.withAsync() option.

    โฑ Timeout

    • โฑ Timeout.withInterrupt(boolean) is now TimeoutBuilder.withInterrupt().

    Execution and AsyncExecution

    • The standalone Execution API, and the AsyncExecution API created via the FailsafeExecutor.runAsyncExecution and getAsyncExecution methods, have been unified to include:
      • record(R, Throwable)
      • recordResult(R)
      • recordException(Throwable)
      • complete()
    • ๐Ÿšš The previously supported Execution and AsyncExecution methods for recording a result have been removed. The methods for performing a retry have also been removed. For Execution, isComplete will indicate whether the execution is complete else if retries can be performed. For AsyncExecution retries will automatically be performed, if possible, immediately after a result or failure is recorded.
    • The Execution constructor is no longer visible. Execution instances must now be constructed via Execution.of(policies).
    • Execution.getWaitTime() was renamed to getDelay().

    Failsafe class

    • ๐Ÿšš Failsafe.with(P[] policies) was removed in favor of Failsafe.with(P, P...). This should only affect users who were explicitly passing an array to Failsafe.with.

    SPI Changes

    โฑ The following changes effect the SPI classes, for users who are extending Failsafe with custom schedulers or policies:

    • โฑ Scheduler and DefauledScheduledFuture were moved to the spi package.
    • ๐Ÿ“ฆ Policy and PolicyExecutor were moved to the spi package and some method signatures changed.
    • ๐Ÿ“ฆ ExecutionResult was moved to the spi package and made generic.
    • ๐Ÿ“ฆ Several new classes were added to the spi package to contain internal execution APIs including ExecutionInternal, SyncExecutionInternal, and AsyncExecutionInternal.
    • ๐Ÿ“ฆ FailsafeFuture was moved to the SPI package and some method signatures changed.

    ๐Ÿ› Bug Fixes

    • ๐Ÿ‘Œ Improved the reliability of async executions, cancellations, and Timeouts.

    ๐Ÿ‘Œ Improvements

    • ๐Ÿ— Issue #47 - All policies and policy config classes are now threadsafe. Policy builders are not threadsafe.
    • ๐Ÿ— Issue #201 - Thread safety is clearly documented in policy, policy config, and policy builder classes.
    • Issue #292 - Created an extensible Policy SPI.
    • Issue #254 - Added an explicit compose method to FailsafeExecutor.
    • Issue #293 - Added RetryPolicyBuilder.withBackoff(Duration, Duration) and .withDelay(Duration, Duration).
    • โฑ Issue #221 - Executor instances configured via FailsafeExecutor.with(Executor) are now used on all executions, including sync executions, and can be used in conjunction with a separately configured ExecutorService or Scheduler for async executions.
    • โž• Added FailsafeExecutor.getPolicies().
    • โž• Added isFirstAttempt() and isRetry() to ExecutionAttempt, which is available via a few event listeners.