Skip to content

A lightweight, easy-to-use fault tolerance library designed for Java8 and functional programming based on javaslang.

License

Notifications You must be signed in to change notification settings

roltean/javaslang-circuitbreaker

 
 

Repository files navigation

Fault tolerance library designed for Java8

Build Status Coverage Status download Apache License 2

This library is a lightweight, easy-to-use fault tolerance library inspired by Netflix Hystrix, but designed solely for Java 8 and functional programming. Lightweight, because the library only uses SLF4J and a functional library for Java 8 called Javaslang. Javaslang itself has no external library dependencies.
The library provides several higher-order functions to decorate any function with a Circuit Breaker. In the following I call the higher-order functions decorators. The decorators return an enhanced version of your function. Furthermore, the library provides a decorator to retry failed functions. You can stack more than one decorator on any given function. That means, you can combine a Retry decorator with a CircuitBreaker decorator. Any decorated function can be invoked synchronously or asynchronously.

The CircuitBreaker is implemented via a finite state machine with three states: CLOSED, OPEN and HALF_OPEN.

state machine

The CircuitBreaker does not know anything about the backend’s state by itself, but uses the information provided by the decorators via CircuitBreaker::recordSuccess() and CircuitBreaker::recordFailure(throwable). See example:

static <T> Supplier<T> decorateSupplier(Supplier<T> supplier, CircuitBreaker circuitBreaker){
    return () -> {
        circuitBreaker.isCallPermitted();
        try {
            T returnValue = supplier.get();
            circuitBreaker.recordSuccess();
            return returnValue;
        } catch (Exception exception) {
            circuitBreaker.recordFailure(exception);
            throw exception;
        }
    };
}

The state of the CircuitBreaker changes from CLOSED to OPEN when the failure rate is above a (configurable) threshold.
Then, all access to the backend is blocked for a (configurable) time duration. CircuitBreaker::isCallPermitted() throws a CircuitBreakerOpenException, if the CircuitBreaker is OPEN.

The CircuitBreaker uses a Ring Bit Buffer in the CLOSED state to store the success or failure statuses of the calls. A successful call is stored as a 0 bit and a failed call is stored as a 1 bit. The Ring Bit Buffer has a (configurable) fixed-size. The Ring Bit Buffer uses internally a BitSet to store the bits which is saving memory compared to a boolean array. The BitSet uses a long[] array to store the bits. That means the BitSet only needs an array of 16 long (64-bit) values to store the status of 1024 calls.

Ring Bit Buffer

The Ring Bit Buffer must be full, before the failure rate can be calculated.
For example, if the size of the Ring Buffer is 10, then at least 10 calls must evaluated, before the failure rate can be calculated. If only 9 calls have been evaluated the CircuitBreaker will not trip open even if all 9 calls have failed.

After the time duration has elapsed, the CircuitBreaker state changes from OPEN to HALF_CLOSED and allows calls to see if the backend is still unavailable or has become available again. The CircuitBreaker uses another (configurable) Ring Bit Buffer to evaluate the failure rate in the HALF_CLOSED state. If the failure rate is above the configured threshold, the state changes back to OPEN. If the failure rate is below or equal to the threshold, the state changes back to CLOSED.
CircuitBreaker::recordFailure(exception) checks if the exception should be recorded as a failure or should be ignored. You can configure a custom Predicate which decides whether an exception should be recorded as a failure. The default Predicate records all exceptions as a failure.

Usage guide

See User Guide.

License

Copyright 2015 Robert Winkler

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

About

A lightweight, easy-to-use fault tolerance library designed for Java8 and functional programming based on javaslang.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 100.0%