Handling failures in Java just got easier thanks to Failsafe
Are you looking for a Java library to help you handle failures in Java 8+? Then this lightweight, zero-dependency library is for you. Let’s have a closer look at Failsafe.
Meet Failsafe, a lightweight, zero-dependency library for handling failures in Java 8+.
Failsafe also provides a concise API for handling everyday use cases and the flexibility to handle everything else.
The concept behind it is quite simple – it works by wrapping executable logic with one or more resilience policies, which can be combined and composed as needed. What’s more, it provides features that allow you to integrate with various scenarios.
Let’s have a closer look at what this tool has to offer.
Failure policies – Failsafe uses policies to handle failures. By default, policies treat any Exception as a failure. But policies can also be configured to handle more specific failures or conditions.
Retries – Retry policies express when retries should be performed for an execution failure. By default, a RetryPolicy will perform a maximum of 3 execution attempts. You can configure a max number of attempts or retries.
Circuit breakers – Circuit breakers allow you to create systems that fail-fast by temporarily disabling execution as a way of preventing system overload. When a configured threshold of execution failures occurs on a circuit breaker, the circuit is opened and further execution requests fail with CircuitBreakerOpenException. After a delay, the circuit is half-opened and trial executions are attempted to determine whether the circuit should be closed or opened again. If the trial executions meet a success threshold, the breaker is closed again and executions will proceed as normal.
Fallbacks – Fallbacks allow you to provide an alternative result for a failed execution. They can also be used to suppress exceptions and provide a default result.
Policy composition – Policies can be composed in any way desired, including multiple policies of the same type. Policies handle execution results in reverse order, similar to the way that function composition works.
Configurable schedulers – By default, Failsafe uses the ForkJoinPool’s common pool to perform async executions, but you can also configure a specific ScheduledExecutorService, custom Scheduler, or ExecutorService to use.
Event listeners – Failsafe supports event listeners, both in the top level Failsafe API, and in the different Policy implementations. At the top level, it can notify you when an execution completes for all policies. It can also notify you when an execution completes successfully for all policies or when an execution fails for any policy. See all the relevant functions here.
Execution context – Failsafe can provide an ExecutionContext containing execution related information such as the number of execution attempts as well as start and elapsed times
Asynchronous API integration – Failsafe can be integrated with asynchronous code that reports completion via callbacks. The runAsyncExecution, getAsyncExecution and futureAsyncExecution methods provide an AsyncExecution reference that can be used to manually schedule retries or complete the execution from inside asynchronous callbacks.
CompletionStage integration – Failsafe can accept a CompletionStage and return a new CompletableFuture with failure handling built-in.
Library and API integration – For library and public API developers, Failsafe integrates nicely into existing APIs, allowing your users to configure retry policies for different operations. One integration approach is to subclass the RetryPolicy class and expose that as part of your API while the rest of Failsafe remains internal. Another approach is to use something like the Maven shade plugin to rename and relocate Failsafe classes into your project’s package structure as desired.
Head over to the GitHub repo for all the information on these features and more
Getting started with Failsafe is fairly simple. Download the latest Failsafe Maven dependency here and add it to your project.