use of io.github.resilience4j.bulkhead.ThreadPoolBulkhead in project resilience4j by resilience4j.
the class DecoratorsTest method testDecorateCallableWithBulkheadFullExceptionFallback.
@Test
public void testDecorateCallableWithBulkheadFullExceptionFallback() throws ExecutionException, InterruptedException {
ThreadPoolBulkhead bulkhead = ThreadPoolBulkhead.ofDefaults("helloBackend");
ThreadPoolBulkhead bulkheadMock = spy(bulkhead);
given(bulkheadMock.submit(any(Callable.class))).willThrow(BulkheadFullException.createBulkheadFullException(bulkhead));
CompletionStage<String> completionStage = Decorators.ofCallable(() -> helloWorldService.returnHelloWorldWithException()).withThreadPoolBulkhead(bulkheadMock).withFallback(BulkheadFullException.class, (e) -> "Fallback").get();
String result = completionStage.toCompletableFuture().get();
assertThat(result).isEqualTo("Fallback");
}
use of io.github.resilience4j.bulkhead.ThreadPoolBulkhead in project resilience4j by resilience4j.
the class DecoratorsTest method testDecorateRunnableWithBulkheadFullExceptionFallback.
@Test
public void testDecorateRunnableWithBulkheadFullExceptionFallback() throws ExecutionException, InterruptedException {
ThreadPoolBulkhead bulkhead = ThreadPoolBulkhead.ofDefaults("helloBackend");
ThreadPoolBulkhead bulkheadMock = spy(bulkhead);
given(bulkheadMock.submit(any(Callable.class))).willThrow(BulkheadFullException.createBulkheadFullException(bulkhead));
CompletionStage<Void> completionStage = Decorators.ofRunnable(() -> helloWorldService.sayHelloWorld()).withThreadPoolBulkhead(bulkheadMock).withFallback(BulkheadFullException.class, (e) -> {
helloWorldService.sayHelloWorld();
return null;
}).get();
completionStage.toCompletableFuture().get();
then(helloWorldService).should(times(1)).sayHelloWorld();
}
use of io.github.resilience4j.bulkhead.ThreadPoolBulkhead in project resilience4j by resilience4j.
the class DecoratorsTest method shouldThrowTimeoutExceptionAndPropagateMDCContext.
@Test
public void shouldThrowTimeoutExceptionAndPropagateMDCContext() {
TimeLimiter timeLimiter = TimeLimiter.of("helloBackend", TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(100)).build());
CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("helloBackend");
ThreadPoolBulkhead bulkhead = ThreadPoolBulkhead.ofDefaults("helloBackend");
MDC.put("key", "ValueShouldPropagateThreadBoundary");
MDC.put("key2", "value2");
final Map<String, String> contextMap = MDC.getCopyOfContextMap();
ContextAwareScheduledThreadPoolExecutor scheduledThreadPool = ContextAwareScheduledThreadPoolExecutor.newScheduledThreadPool().corePoolSize(1).build();
CompletionStage<String> completionStage = Decorators.ofCallable(() -> {
assertThat(Thread.currentThread().getName()).isEqualTo("bulkhead-helloBackend-1");
Thread.sleep(1000);
return "Bla";
}).withThreadPoolBulkhead(bulkhead).withTimeLimiter(timeLimiter, scheduledThreadPool).withCircuitBreaker(circuitBreaker).get();
final CompletableFuture<String> completableFuture = completionStage.toCompletableFuture().exceptionally(throwable -> {
if (throwable != null) {
assertThat(Thread.currentThread().getName()).isEqualTo("ContextAwareScheduledThreadPool-1");
assertThat(MDC.getCopyOfContextMap()).hasSize(2).containsExactlyEntriesOf(contextMap);
return MDC.getCopyOfContextMap().get("key");
}
return null;
});
waitAtMost(2, TimeUnit.SECONDS).until(matches(() -> assertThat(completableFuture).isCompletedWithValue("ValueShouldPropagateThreadBoundary")));
CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(1);
assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(1);
}
use of io.github.resilience4j.bulkhead.ThreadPoolBulkhead in project resilience4j by resilience4j.
the class DecoratorsTest method testDecorateCompletionStageWithTimeoutExceptionFallback.
@Test
public void testDecorateCompletionStageWithTimeoutExceptionFallback() throws ExecutionException, InterruptedException {
TimeLimiter timeLimiter = TimeLimiter.of("helloBackend", TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(100)).build());
CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("helloBackend");
ThreadPoolBulkhead bulkhead = ThreadPoolBulkhead.ofDefaults("helloBackend");
CompletionStage<String> completionStage = Decorators.ofCallable(() -> {
Thread.sleep(1000);
return "Bla";
}).withThreadPoolBulkhead(bulkhead).withTimeLimiter(timeLimiter, Executors.newSingleThreadScheduledExecutor()).withCircuitBreaker(circuitBreaker).withFallback(TimeoutException.class, (e) -> "Fallback").get();
String result = completionStage.toCompletableFuture().get();
assertThat(result).isEqualTo("Fallback");
CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(1);
}
use of io.github.resilience4j.bulkhead.ThreadPoolBulkhead in project resilience4j by resilience4j.
the class TaggedThreadPoolBulkheadMetricsPublisherTest method testReplaceNewMeter.
@Test
public void testReplaceNewMeter() {
ThreadPoolBulkhead oldOne = ThreadPoolBulkhead.of("backendC", ThreadPoolBulkheadConfig.ofDefaults());
// add meters of old
taggedBulkheadMetricsPublisher.addMetrics(meterRegistry, oldOne);
// one success call
oldOne.executeSupplier(() -> "Bla");
assertThat(taggedBulkheadMetricsPublisher.meterIdMap).containsKeys("backendC");
assertThat(taggedBulkheadMetricsPublisher.meterIdMap.get("backendC")).hasSize(EXPECTED_METER_COUNT);
Collection<Gauge> gauges = meterRegistry.get(DEFAULT_MAX_THREAD_POOL_SIZE_METRIC_NAME).gauges();
Optional<Gauge> successful = findMeterByNamesTag(gauges, oldOne.getName());
assertThat(successful).isPresent();
assertThat(successful.get().value()).isEqualTo(oldOne.getMetrics().getMaximumThreadPoolSize());
ThreadPoolBulkhead newOne = ThreadPoolBulkhead.of("backendC", ThreadPoolBulkheadConfig.ofDefaults());
// add meters of new
taggedBulkheadMetricsPublisher.addMetrics(meterRegistry, newOne);
// three success call
newOne.executeSupplier(() -> "Bla");
newOne.executeSupplier(() -> "Bla");
newOne.executeSupplier(() -> "Bla");
assertThat(taggedBulkheadMetricsPublisher.meterIdMap).containsKeys("backendC");
assertThat(taggedBulkheadMetricsPublisher.meterIdMap.get("backendC")).hasSize(EXPECTED_METER_COUNT);
gauges = meterRegistry.get(DEFAULT_MAX_THREAD_POOL_SIZE_METRIC_NAME).gauges();
successful = findMeterByNamesTag(gauges, newOne.getName());
assertThat(successful).isPresent();
assertThat(successful.get().value()).isEqualTo(newOne.getMetrics().getMaximumThreadPoolSize());
}
Aggregations