HomeGuidesChangelog
GuidesGitHubLog In
Guides

Examples

Examples of resilience4j-circuitbreaker

Create a CircuitBreakerRegistry

Create a CircuitBreakerRegistry with a custom CircuitBreakerConfig.

// Create a custom configuration for a CircuitBreaker CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom() .failureRateThreshold(50) .waitDurationInOpenState(Duration.ofMillis(1000)) .permittedNumberOfCallsInHalfOpenState(2) .slidingWindowSize(2) .recordExceptions(IOException.class, TimeoutException.class) .ignoreExceptions(BusinessException.class, OtherBusinessException.class) .build(); // Create a CircuitBreakerRegistry with a custom global configuration CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.of(circuitBreakerConfig);

Create a CircuitBreaker

Get a CircuitBreaker from the CircuitBreakerRegistry with the global default configuration

CircuitBreaker circuitBreaker = circuitBreakerRegistry .circuitBreaker("name");

Decorate a functional interface

Decorate your call to BackendService.doSomething() with a CircuitBreaker and execute the decorated supplier and recover from any exception.

Supplier<String> decoratedSupplier = CircuitBreaker .decorateSupplier(circuitBreaker, backendService::doSomething); String result = Try.ofSupplier(decoratedSupplier) .recover(throwable -> "Hello from Recovery").get();

Execute a decorated functional interface

When you don't want to decorate your lambda expression, but just execute it and protect the call by a CircuitBreaker.

String result = circuitBreaker .executeSupplier(backendService::doSomething);

Recover from an exception

If you want to recover from an exception after the CircuitBreaker recorded it as a failure, you can chain the method Try.recover(). The recovery method is only invoked, if Try.of() returns a Failure<Throwable> Monad.

// Given CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("testName"); // When I decorate my function and invoke the decorated function CheckedFunction0<String> checkedSupplier = CircuitBreaker.decorateCheckedSupplier(circuitBreaker, () -> { throw new RuntimeException("BAM!"); }); Try<String> result = Try.of(checkedSupplier) .recover(throwable -> "Hello Recovery"); // Then the function should be a success, // because the exception could be recovered assertThat(result.isSuccess()).isTrue(); // and the result must match the result of the recovery function. assertThat(result.get()).isEqualTo("Hello Recovery");

If you want to recover from an exception before the CircuitBreaker records it as a failure, you can do the following:

Supplier<String> supplier = () -> { throw new RuntimeException("BAM!"); }; Supplier<String> supplierWithRecovery = SupplierUtils .recover(supplier, (exception) -> "Hello Recovery"); String result = circuitBreaker.executeSupplier(supplierWithRecovery); assertThat(result).isEqualTo("Hello Recovery");

SupplierUtils and CallableUtils contain other methods like andThen which can take can be used to chain functions. For example to check the status code of a HTTP response, so that exceptions can be thrown.

Supplier<String> supplierWithResultAndExceptionHandler = SupplierUtils .andThen(supplier, (result, exception) -> "Hello Recovery"); Supplier<HttpResponse> supplier = () -> httpClient.doRemoteCall(); Supplier<HttpResponse> supplierWithResultHandling = SupplierUtils.andThen(supplier, result -> { if (result.getStatusCode() == 400) { throw new ClientException(); } else if (result.getStatusCode() == 500) { throw new ServerException(); } return result; }); HttpResponse httpResponse = circuitBreaker .executeSupplier(supplierWithResultHandling);

Reset CircuitBreaker

The Circuit Breaker supports resetting to its original state, losing all the metrics and effectively resetting its Sliding Window.

CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("testName"); circuitBreaker.reset();

Transition to states manually

CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("testName"); circuitBreaker.transitionToDisabledState(); // circuitBreaker.onFailure(...) won't trigger a state change circuitBreaker.transitionToClosedState(); // will transition to CLOSED state and re-enable normal behaviour, keeping metrics circuitBreaker.transitionToForcedOpenState(); // circuitBreaker.onSuccess(...) won't trigger a state change circuitBreaker.reset(); // will transition to CLOSED state and re-enable normal behaviour, losing metrics

Override the RegistryStore

You can override the im-memory RegistryStore by a custom implementation. For example, if you want to use a Cache which removes unused instances after a certain period of time.

CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.custom() .withRegistryStore(new CacheCircuitBreakerRegistryStore()) .build();