Overview
Fault Tolerance is part of the MicroProfile set of specifications. This API defines mostly annotations that improve application robustness by providing support to conveniently handle error conditions (faults) that may occur in real-world applications. Examples include service restarts, network delays, temporal infrastructure instabilities, etc.
Maven Coordinates
To enable MicroProfile Fault Tolerance,
either add a dependency on the helidon-microprofile bundle or
add the following dependency to your project’s pom.xml (see
Managing Dependencies).
<dependency>
<groupId>io.helidon.microprofile</groupId>
<artifactId>helidon-microprofile-fault-tolerance</artifactId>
</dependency>
API
The MicroProfile Fault Tolerance specification defines a set of annotations to decorate classes and methods in your application for the purpose of improving its robustness. Many of these annotations can be applied at the class or method level: if applied at the class level, they will impact all methods in the class; if applied both at the class and method level, the latter will take precedence over the former.
The following table provides a brief description of each of these annotations, including its parameters and default values.
| Annotation | Description |
|---|---|
@Retry(
maxRetries=3,
delay=0,
delayUnit=ChronoUnit.MILLIS,
maxDuration=180000,
durationUnit=ChronoUnit.MILLIS,
jitter=200,
jitterDelayUnit=ChronoUnit.MILLIS,
retryOn={Exception.class},
abortOn={}
)
|
Retries the execution of a method if a failure is encountered. Annotation attributes can be used to control the number of retries, delay between retries and which exceptions to retry or abort on. |
@Timeout(
value=1000,
unit=ChronoUnit.MILLIS
)
|
Defines an upper bound on a method’s execution time. Default value is 1 second. |
@CircuitBreaker(
failOn={Throwable.class},
skipOn={},
delay=5000,
delayUnit=ChronoUnit.MILLIS,
requestVolumeThreshold=20,
failureRation=.50,
successThreshold=1
)
|
Defines a policy to avoid repeated execution of logic that is likely to fail. A circuit breaker can be closed, open or half-open. In closed state a circuit breaker will execute logic normally. In open state a circuit breaker will prevent execution of logic that has been seen to fail. Finally, in half-open state a circuit breaker will allow trial executions in an attempt to switch its internal state to closed. The other annotation parameters are used to control how these state transitions are triggered. |
@Bulkhead(
value=10,
waitingTaskQueue=10
)
|
Defines a policy to limit the number of concurrent executions allowed over some
application logic. A queue is used to park tasks awaiting execution after
the limit has been reached. A queue is only active when invocations are
|
@Fallback(
value=DEFAULT.class,
fallbackMethod="",
applyOn={Throwable.class},
skipOn={}
)
|
Establishes a handler to be executed upon encountering an invocation failure. A handler
is either a class that implements |
@Asynchronous |
Executes an invocation asynchronously without blocking the calling thread. Annotated
method must return |
Configuration
Helidon’s implementation uses two types of thread pools: normal and scheduled. The default
core size of these executors is 20; however, that can be configured using an application.yaml
file as follows:
executor:
core-pool-size: 32
scheduled-executor:
core-pool-size: 32
|
Note
|
There is currently no support to configure these executor properties via a
microprofile-config.properties file.
|
For a complete set of properties available to configure these executors, see ThreadPoolConfig. ScheduledThreadPoolConfig.
Examples
-
The method
retryWithFallbackshall be called at most 3 times, first call plus 2 retries, with a delay of 400 milliseconds between calls. If none of the calls is successful, theonFailuremethod shall be called as a fallback mechanism.@Retry(maxRetries = 2, delay = 400L) @Fallback(fallbackMethod = "onFailure") String retryWithFallback() { return getMyValue(); } -
The method
timedCircuitBreakerdefines a rolling window of size 10 and a policy to open the circuit breaker after 4 or more failures occur in that window, and to transition back to half-open state after 3 consecutive and successful runs. Additionally, it sets an overall timeout for the invocation of 1.5 seconds.@Timeout(1500) @CircuitBreaker(requestVolumeThreshold = 10, failureRatio = .4, successThreshold = 3) void timedCircuitBreaker() throws InterruptedException { //... } -
The method
executeWithQueueAndFallbackdefines a bulkhead that will limit the number of concurrent calls to a maximum of 2; any additional tasks shall be queued up to a maximum of 10. Finally, if an error occurs theonFailuremethod shall be called as a fallback mechanism. The@Asynchronousannotation is needed to enable queueing of bulkhead tasks.@Asynchronous @Fallback(fallbackMethod = "onFailure") @Bulkhead(value = 2, waitingTaskQueue = 10) CompletableFuture<String> executeWithQueueAndFallback() { return getMyValueAsync(); }
Additional Information
For additional information about this API, see the MicroProfile Fault Tolerance Javadocs.