use of io.github.resilience4j.bulkhead.Bulkhead in project resilience4j by resilience4j.
the class BulkheadMetricsTest method shouldUseCustomPrefix.
@Test
public void shouldUseCustomPrefix() throws Throwable {
// Given
BulkheadRegistry bulkheadRegistry = BulkheadRegistry.ofDefaults();
Bulkhead bulkhead = bulkheadRegistry.bulkhead("testBulkhead");
metricRegistry.registerAll(BulkheadMetrics.ofIterable("testPre", bulkheadRegistry.getAllBulkheads()));
// Given latch to verify bulkhead
CountDownLatch countDownLatch = new CountDownLatch(1);
// Given the HelloWorldService returns Hello world
BDDMockito.given(helloWorldService.returnHelloWorld()).will(invocation -> {
if (countDownLatch.await(10, TimeUnit.SECONDS)) {
return "Hello world";
} else {
throw new IllegalStateException("Timeout - test failure");
}
});
// When
Future<String> future = executorService.submit(() -> bulkhead.executeSupplier(helloWorldService::returnHelloWorld));
// Then metrics are present and show value
assertThat(metricRegistry.getMetrics()).hasSize(1);
assertThat(metricRegistry.getGauges().get("testPre.testBulkhead.available_concurrent_calls").getValue()).isIn(DEFAULT_MAX_CONCURRENT_CALLS, DEFAULT_MAX_CONCURRENT_CALLS - 1);
// Then release latch and verify result
countDownLatch.countDown();
assertThat(future.get(10, TimeUnit.SECONDS)).isEqualTo("Hello world");
BDDMockito.then(helloWorldService).should(times(1)).returnHelloWorld();
// Then check metrics again
assertThat(metricRegistry.getMetrics()).hasSize(1);
assertThat(metricRegistry.getGauges().get("testPre.testBulkhead.available_concurrent_calls").getValue()).isIn(DEFAULT_MAX_CONCURRENT_CALLS, DEFAULT_MAX_CONCURRENT_CALLS);
}
use of io.github.resilience4j.bulkhead.Bulkhead in project resilience4j by resilience4j.
the class BulkheadTransformer method apply.
@Override
public Upstream<T> apply(Upstream<? extends T> upstream) throws Exception {
return down -> {
if (bulkhead.isCallPermitted()) {
// do not allow permits to leak
upstream.connect(new Downstream<T>() {
@Override
public void success(T value) {
bulkhead.onComplete();
down.success(value);
}
@Override
public void error(Throwable throwable) {
bulkhead.onComplete();
try {
if (recover != null) {
down.success(recover.apply(throwable));
} else {
down.error(throwable);
}
} catch (Throwable t) {
down.error(t);
}
}
@Override
public void complete() {
bulkhead.onComplete();
down.complete();
}
});
} else {
Throwable t = new BulkheadFullException(String.format("Bulkhead '%s' is full", bulkhead.getName()));
if (recover != null) {
try {
down.success(recover.apply(t));
} catch (Throwable t2) {
down.error(t2);
}
} else {
down.error(t);
}
}
};
}
use of io.github.resilience4j.bulkhead.Bulkhead in project resilience4j by resilience4j.
the class BulkheadChain method execute.
@Override
public void execute(Chain chain) throws Exception {
String prefix = chain.getRegistry().get(Resilience4jConfig.class).getEndpoints().getBulkheads().getPath();
chain.prefix(prefix, chain1 -> {
chain1.get("events", ctx -> Promise.<BulkheadEventsEndpointResponse>async(d -> {
BulkheadEventsEndpointResponse response = new BulkheadEventsEndpointResponse(eventConsumerRegistry.getAllEventConsumer().flatMap(CircularEventConsumer::getBufferedEvents).sorted(Comparator.comparing(BulkheadEvent::getCreationTime)).map(BulkheadEventDTO::createEventDTO).toJavaList());
d.success(response);
}).then(r -> ctx.render(Jackson.json(r))));
chain1.get("stream/events", ctx -> {
Seq<Flowable<BulkheadEvent>> eventStreams = bulkheadRegistry.getAllBulkheads().map(bulkhead -> RxJava2Adapter.toFlowable(bulkhead.getEventPublisher()));
Function<BulkheadEvent, String> data = b -> Jackson.getObjectWriter(chain1.getRegistry()).writeValueAsString(BulkheadEventDTO.createEventDTO(b));
ServerSentEvents events = ServerSentEvents.serverSentEvents(Flowable.merge(eventStreams), e -> e.id(BulkheadEvent::getBulkheadName).event(c -> c.getEventType().name()).data(data));
ctx.render(events);
});
chain1.get("events/:name", ctx -> {
String bulkheadName = ctx.getPathTokens().get("name");
Promise.<BulkheadEventsEndpointResponse>async(d -> {
BulkheadEventsEndpointResponse response = new BulkheadEventsEndpointResponse(eventConsumerRegistry.getEventConsumer(bulkheadName).getBufferedEvents().map(BulkheadEventDTO::createEventDTO).toJavaList());
d.success(response);
}).then(r -> ctx.render(Jackson.json(r)));
});
chain1.get("stream/events/:name", ctx -> {
String bulkheadName = ctx.getPathTokens().get("name");
Bulkhead bulkhead = bulkheadRegistry.getAllBulkheads().find(b -> b.getName().equals(bulkheadName)).getOrElseThrow(() -> new IllegalArgumentException(String.format("bulkhead with name %s not found", bulkheadName)));
Function<BulkheadEvent, String> data = b -> Jackson.getObjectWriter(chain1.getRegistry()).writeValueAsString(BulkheadEventDTO.createEventDTO(b));
ServerSentEvents events = ServerSentEvents.serverSentEvents(RxJava2Adapter.toFlowable(bulkhead.getEventPublisher()), e -> e.id(BulkheadEvent::getBulkheadName).event(c -> c.getEventType().name()).data(data));
ctx.render(events);
});
chain1.get("events/:name/:type", ctx -> {
String bulkheadName = ctx.getPathTokens().get("name");
String eventType = ctx.getPathTokens().get("type");
Promise.<BulkheadEventsEndpointResponse>async(d -> {
BulkheadEventsEndpointResponse response = new BulkheadEventsEndpointResponse(eventConsumerRegistry.getEventConsumer(bulkheadName).getBufferedEvents().filter(event -> event.getEventType() == BulkheadEvent.Type.valueOf(eventType.toUpperCase())).map(BulkheadEventDTO::createEventDTO).toJavaList());
d.success(response);
}).then(r -> ctx.render(Jackson.json(r)));
});
chain1.get("stream/events/:name/:type", ctx -> {
String bulkheadName = ctx.getPathTokens().get("name");
String eventType = ctx.getPathTokens().get("type");
Bulkhead bulkhead = bulkheadRegistry.getAllBulkheads().find(b -> b.getName().equals(bulkheadName)).getOrElseThrow(() -> new IllegalArgumentException(String.format("bulkhead with name %s not found", bulkheadName)));
Flowable<BulkheadEvent> eventStream = RxJava2Adapter.toFlowable(bulkhead.getEventPublisher()).filter(event -> event.getEventType() == BulkheadEvent.Type.valueOf(eventType.toUpperCase()));
Function<BulkheadEvent, String> data = b -> Jackson.getObjectWriter(chain1.getRegistry()).writeValueAsString(BulkheadEventDTO.createEventDTO(b));
ServerSentEvents events = ServerSentEvents.serverSentEvents(eventStream, e -> e.id(BulkheadEvent::getBulkheadName).event(c -> c.getEventType().name()).data(data));
ctx.render(events);
});
});
}
use of io.github.resilience4j.bulkhead.Bulkhead in project resilience4j by resilience4j.
the class BulkheadMetricsTest method shouldRegisterMetrics.
@Test
public void shouldRegisterMetrics() throws Throwable {
// Given
BulkheadRegistry bulkheadRegistry = BulkheadRegistry.ofDefaults();
Bulkhead bulkhead = bulkheadRegistry.bulkhead("testBulkhead");
metricRegistry.registerAll(BulkheadMetrics.ofBulkhead(bulkhead));
// Given latch to verify bulkhead
CountDownLatch countDownLatch = new CountDownLatch(1);
// Given the HelloWorldService returns Hello world
BDDMockito.given(helloWorldService.returnHelloWorld()).will(invocation -> {
if (countDownLatch.await(10, TimeUnit.SECONDS)) {
return "Hello world";
} else {
throw new IllegalStateException("Timeout - test failure");
}
});
// When
Future<String> future = executorService.submit(() -> bulkhead.executeSupplier(helloWorldService::returnHelloWorld));
// Then metrics are present and show value
assertThat(metricRegistry.getMetrics()).hasSize(1);
assertThat(metricRegistry.getGauges().get("resilience4j.bulkhead.testBulkhead.available_concurrent_calls").getValue()).isIn(DEFAULT_MAX_CONCURRENT_CALLS, DEFAULT_MAX_CONCURRENT_CALLS - 1);
// Then release latch and verify result
countDownLatch.countDown();
assertThat(future.get(10, TimeUnit.SECONDS)).isEqualTo("Hello world");
BDDMockito.then(helloWorldService).should(times(1)).returnHelloWorld();
// Then check metrics again
assertThat(metricRegistry.getMetrics()).hasSize(1);
assertThat(metricRegistry.getGauges().get("resilience4j.bulkhead.testBulkhead.available_concurrent_calls").getValue()).isIn(DEFAULT_MAX_CONCURRENT_CALLS, DEFAULT_MAX_CONCURRENT_CALLS);
}
use of io.github.resilience4j.bulkhead.Bulkhead in project resilience4j by resilience4j.
the class BulkheadMetrics method bindTo.
@Override
public void bindTo(MeterRegistry registry) {
for (Bulkhead bulkhead : bulkheads) {
final String name = bulkhead.getName();
Gauge.builder(getName(prefix, name, AVAILABLE_CONCURRENT_CALLS), bulkhead, (cb) -> cb.getMetrics().getAvailableConcurrentCalls()).register(registry);
}
}
Aggregations