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));
}
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);
}
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()));
}
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);
}
}
};
}
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;
}
Aggregations