diff --git a/spring-cloud-circuitbreaker-resilience4j/src/main/java/org/springframework/cloud/circuitbreaker/resilience4j/Resilience4jBulkheadProvider.java b/spring-cloud-circuitbreaker-resilience4j/src/main/java/org/springframework/cloud/circuitbreaker/resilience4j/Resilience4jBulkheadProvider.java index 8994ba4..f3532e3 100644 --- a/spring-cloud-circuitbreaker-resilience4j/src/main/java/org/springframework/cloud/circuitbreaker/resilience4j/Resilience4jBulkheadProvider.java +++ b/spring-cloud-circuitbreaker-resilience4j/src/main/java/org/springframework/cloud/circuitbreaker/resilience4j/Resilience4jBulkheadProvider.java @@ -16,10 +16,11 @@ package org.springframework.cloud.circuitbreaker.resilience4j; +import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -30,6 +31,7 @@ import io.github.resilience4j.bulkhead.ThreadPoolBulkhead; import io.github.resilience4j.bulkhead.ThreadPoolBulkheadRegistry; import io.github.resilience4j.circuitbreaker.CircuitBreaker; import io.github.resilience4j.timelimiter.TimeLimiter; +import io.vavr.control.Try; import org.springframework.cloud.client.circuitbreaker.Customizer; @@ -106,17 +108,11 @@ public class Resilience4jBulkheadProvider { public T run(String id, Supplier toRun, Function fallback, CircuitBreaker circuitBreaker, TimeLimiter timeLimiter) { Supplier> bulkheadCall = decorateBulkhead(id, toRun); - Supplier> timeLimiterCall = timeLimiter - .decorateCompletionStage(Executors.newSingleThreadScheduledExecutor(), - bulkheadCall); - Supplier> circuitBreakerCall = circuitBreaker - .decorateCompletionStage(timeLimiterCall); - try { - return circuitBreakerCall.get().toCompletableFuture().get(); - } - catch (Exception e) { - return fallback.apply(e); - } + final Callable timeLimiterCall = decorateTimeLimiter(bulkheadCall, + timeLimiter); + final Callable circuitBreakerCall = circuitBreaker + .decorateCallable(timeLimiterCall); + return Try.of(circuitBreakerCall::call).recover(fallback).get(); } private Supplier> decorateBulkhead(final String id, @@ -138,4 +134,11 @@ public class Resilience4jBulkheadProvider { } } + private Callable decorateTimeLimiter( + final Supplier> supplier, TimeLimiter timeLimiter) { + final Supplier> futureSupplier = () -> supplier.get() + .toCompletableFuture(); + return timeLimiter.decorateFutureSupplier(futureSupplier); + } + }