Search in sources :

Example 1 with CircuitBreaker

use of io.github.resilience4j.circuitbreaker.CircuitBreaker in project resilience4j by resilience4j.

the class CircuitBreakerExportsTest method testExportsCircuitBreakerStates.

@Test
public void testExportsCircuitBreakerStates() {
    // Given
    final CollectorRegistry registry = new CollectorRegistry();
    final CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("foo");
    CircuitBreakerExports.ofIterable("boo_circuit_breaker", singletonList(circuitBreaker)).register(registry);
    final Supplier<Map<String, Double>> values = () -> HashSet.of("closed", "open", "half_open").map(state -> Tuple.of(state, registry.getSampleValue("boo_circuit_breaker_states", new String[] { "name", "state" }, new String[] { "foo", state }))).toMap(t -> t);
    // When
    final Map<String, Double> closedStateValues = values.get();
    circuitBreaker.transitionToOpenState();
    final Map<String, Double> openStateValues = values.get();
    circuitBreaker.transitionToHalfOpenState();
    final Map<String, Double> halfOpenStateValues = values.get();
    circuitBreaker.transitionToClosedState();
    final Map<String, Double> closedStateValues2 = values.get();
    // Then
    assertThat(closedStateValues).isEqualTo(HashMap.of("closed", 1.0, "open", 0.0, "half_open", 0.0));
    assertThat(openStateValues).isEqualTo(HashMap.of("closed", 0.0, "open", 1.0, "half_open", 0.0));
    assertThat(halfOpenStateValues).isEqualTo(HashMap.of("closed", 0.0, "open", 0.0, "half_open", 1.0));
    assertThat(closedStateValues2).isEqualTo(HashMap.of("closed", 1.0, "open", 0.0, "half_open", 0.0));
}
Also used : Tuple(io.vavr.Tuple) CollectorRegistry(io.prometheus.client.CollectorRegistry) CircuitBreaker(io.github.resilience4j.circuitbreaker.CircuitBreaker) InMemoryCircuitBreakerRegistry(io.github.resilience4j.circuitbreaker.internal.InMemoryCircuitBreakerRegistry) HashMap(io.vavr.collection.HashMap) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Test(org.junit.Test) Supplier(java.util.function.Supplier) CircuitBreakerOpenException(io.github.resilience4j.circuitbreaker.CircuitBreakerOpenException) CircuitBreakerRegistry(io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry) Collections.singletonList(java.util.Collections.singletonList) Collections.singleton(java.util.Collections.singleton) HashSet(io.vavr.collection.HashSet) Map(io.vavr.collection.Map) CircuitBreaker(io.github.resilience4j.circuitbreaker.CircuitBreaker) CollectorRegistry(io.prometheus.client.CollectorRegistry) HashMap(io.vavr.collection.HashMap) Map(io.vavr.collection.Map) Test(org.junit.Test)

Example 2 with CircuitBreaker

use of io.github.resilience4j.circuitbreaker.CircuitBreaker in project resilience4j by resilience4j.

the class CircularEventConsumerTest method shouldNotBufferEvents.

@Test
public void shouldNotBufferEvents() {
    // Given
    CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("testName");
    CircularEventConsumer<CircuitBreakerEvent> ringBuffer = new CircularEventConsumer<>(2);
    assertThat(ringBuffer.getBufferedEvents()).isEmpty();
    circuitBreaker.onError(0, new RuntimeException("Bla"));
    circuitBreaker.onError(0, new RuntimeException("Bla"));
    circuitBreaker.onError(0, new RuntimeException("Bla"));
    // Subscription is too late
    circuitBreaker.getEventPublisher().onEvent(ringBuffer);
    // Then
    CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
    assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(3);
    assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(3);
    // Should store 0 events, because Subscription was too late
    assertThat(ringBuffer.getBufferedEvents()).hasSize(0);
}
Also used : CircuitBreaker(io.github.resilience4j.circuitbreaker.CircuitBreaker) CircuitBreakerEvent(io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent) Test(org.junit.Test)

Example 3 with CircuitBreaker

use of io.github.resilience4j.circuitbreaker.CircuitBreaker in project resilience4j by resilience4j.

the class CircularEventConsumerTest method shouldBufferAllEvents.

@Test
public void shouldBufferAllEvents() {
    // Given
    CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom().ringBufferSizeInClosedState(3).recordFailure(throwable -> API.Match(throwable).of(Case($(instanceOf(WebServiceException.class)), true), Case($(), false))).build();
    CircuitBreaker circuitBreaker = CircuitBreaker.of("testName", circuitBreakerConfig);
    CircularEventConsumer<CircuitBreakerEvent> ringBuffer = new CircularEventConsumer<>(10);
    circuitBreaker.getEventPublisher().onEvent(ringBuffer);
    assertThat(ringBuffer.getBufferedEvents()).isEmpty();
    // When
    circuitBreaker.onSuccess(0);
    circuitBreaker.onError(0, new WebServiceException("Bla"));
    circuitBreaker.onError(0, new IOException("Bla"));
    circuitBreaker.onError(0, new WebServiceException("Bla"));
    // Then
    CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
    assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(3);
    assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(2);
    circuitBreaker.reset();
    CircuitBreaker.Metrics resetMetrics = circuitBreaker.getMetrics();
    assertThat(resetMetrics.getNumberOfBufferedCalls()).isEqualTo(0);
    assertThat(resetMetrics.getNumberOfFailedCalls()).isEqualTo(0);
    // Should store 3 events, because circuit emits 2 error events and one state transition event
    assertThat(ringBuffer.getBufferedEvents()).hasSize(7);
    assertThat(ringBuffer.getBufferedEvents()).extracting("eventType").containsExactly(Type.SUCCESS, Type.ERROR, Type.IGNORED_ERROR, Type.ERROR, Type.STATE_TRANSITION, Type.STATE_TRANSITION, Type.RESET);
// ringBuffer.getBufferedEvents().forEach(event -> LOG.info(event.toString()));
}
Also used : CircuitBreakerConfig(io.github.resilience4j.circuitbreaker.CircuitBreakerConfig) WebServiceException(javax.xml.ws.WebServiceException) Predicates.instanceOf(io.vavr.Predicates.instanceOf) CircuitBreaker(io.github.resilience4j.circuitbreaker.CircuitBreaker) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Type(io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent.Type) Test(org.junit.Test) IOException(java.io.IOException) Case(io.vavr.API.Case) API(io.vavr.API) CircuitBreakerEvent(io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent) API.$(io.vavr.API.$) CircuitBreaker(io.github.resilience4j.circuitbreaker.CircuitBreaker) CircuitBreakerEvent(io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent) WebServiceException(javax.xml.ws.WebServiceException) IOException(java.io.IOException) CircuitBreakerConfig(io.github.resilience4j.circuitbreaker.CircuitBreakerConfig) Test(org.junit.Test)

Example 4 with CircuitBreaker

use of io.github.resilience4j.circuitbreaker.CircuitBreaker in project resilience4j by resilience4j.

the class CircuitBreakerTransformer method apply.

@Override
public Upstream<T> apply(Upstream<? extends T> upstream) throws Exception {
    return down -> {
        long start;
        if (circuitBreaker.isCallPermitted()) {
            start = System.nanoTime();
            upstream.connect(new Downstream<T>() {

                @Override
                public void success(T value) {
                    long durationInNanos = System.nanoTime() - start;
                    circuitBreaker.onSuccess(durationInNanos);
                    down.success(value);
                }

                @Override
                public void error(Throwable throwable) {
                    long durationInNanos = System.nanoTime() - start;
                    circuitBreaker.onError(durationInNanos, throwable);
                    try {
                        if (recoverer != null) {
                            down.success(recoverer.apply(throwable));
                        } else {
                            down.error(throwable);
                        }
                    } catch (Throwable t) {
                        down.error(t);
                    }
                }

                @Override
                public void complete() {
                    down.complete();
                }
            });
        } else {
            Throwable t = new CircuitBreakerOpenException(String.format("CircuitBreaker '%s' is open", circuitBreaker.getName()));
            if (recoverer != null) {
                try {
                    down.success(recoverer.apply(t));
                } catch (Throwable t2) {
                    down.error(t2);
                }
            } else {
                down.error(t);
            }
        }
    };
}
Also used : Downstream(ratpack.exec.Downstream) Function(ratpack.func.Function) CircuitBreaker(io.github.resilience4j.circuitbreaker.CircuitBreaker) Upstream(ratpack.exec.Upstream) CircuitBreakerOpenException(io.github.resilience4j.circuitbreaker.CircuitBreakerOpenException) Downstream(ratpack.exec.Downstream) CircuitBreakerOpenException(io.github.resilience4j.circuitbreaker.CircuitBreakerOpenException)

Example 5 with CircuitBreaker

use of io.github.resilience4j.circuitbreaker.CircuitBreaker in project resilience4j by resilience4j.

the class CircuitBreakerHealthIndicator method addDetails.

private Health.Builder addDetails(Health.Builder builder, CircuitBreaker circuitBreaker) {
    CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
    CircuitBreakerConfig config = circuitBreaker.getCircuitBreakerConfig();
    builder.withDetail(FAILURE_RATE, metrics.getFailureRate() + "%").withDetail(FAILURE_RATE_THRESHOLD, config.getFailureRateThreshold() + "%").withDetail(MAX_BUFFERED_CALLS, metrics.getMaxNumberOfBufferedCalls()).withDetail(BUFFERED_CALLS, metrics.getNumberOfBufferedCalls()).withDetail(FAILED_CALLS, metrics.getNumberOfFailedCalls()).withDetail(NOT_PERMITTED, metrics.getNumberOfNotPermittedCalls());
    return builder;
}
Also used : CircuitBreaker(io.github.resilience4j.circuitbreaker.CircuitBreaker) CircuitBreakerConfig(io.github.resilience4j.circuitbreaker.CircuitBreakerConfig)

Aggregations

CircuitBreaker (io.github.resilience4j.circuitbreaker.CircuitBreaker)26 Test (org.junit.Test)19 CircuitBreakerRegistry (io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry)9 CircuitBreakerConfig (io.github.resilience4j.circuitbreaker.CircuitBreakerConfig)6 CircuitBreakerEvent (io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent)6 CircuitBreakerOpenException (io.github.resilience4j.circuitbreaker.CircuitBreakerOpenException)3 InMemoryCircuitBreakerRegistry (io.github.resilience4j.circuitbreaker.internal.InMemoryCircuitBreakerRegistry)3 Type (io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent.Type)2 CircularEventConsumer (io.github.resilience4j.consumer.CircularEventConsumer)2 EventConsumerRegistry (io.github.resilience4j.consumer.EventConsumerRegistry)2 CollectorRegistry (io.prometheus.client.CollectorRegistry)2 CheckedRunnable (io.vavr.CheckedRunnable)2 Tuple (io.vavr.Tuple)2 HashMap (io.vavr.collection.HashMap)2 HashSet (io.vavr.collection.HashSet)2 Map (io.vavr.collection.Map)2 Seq (io.vavr.collection.Seq)2 Duration (java.time.Duration)2 ArrayList (java.util.ArrayList)2 Comparator (java.util.Comparator)2