TimeoutException does not OPEN circuit in resilience4j. Why?

395 Views Asked by At

I am using below code, and what I have seen is BulkheadFullException and RuntimeException is changing the state of circuitbreaker from CLOSED to OPEN, whereas that's not the case with TimeoutException.

@CircuitBreaker(name = "primary", fallbackMethod = "fallbackHandler")
@TimeLimiter(name = "primary")
@Bulkhead(name = "primary", type = Type.THREADPOOL)
public CompletableFuture<String> primaryHandler(String input) {
    return CompletableFuture.completedFuture(process(input));
}

public Object process(String input) {
    
    // TimeoutException will be thrown here by TimeLimiter as timeout is set to 10 seconds.
    try {
        Thread.sleep(15000);
    } catch (Exception e) {}
    
    return null;
}

public CompletableFuture<Object> fallbackHandler(String input, Exception e) {

    // 1. timeout exception is being captured here, but it's not opening the circuit breaker.
    // 2. BulkheadfullException is also being captured here, which is opening the circuit breaker.
    // 3. Any other RuntimeException which is captured here is opening the circuit breaker.

    log.error("primary fallback triggered. Error:", e);
    return CompletableFuture.completedFuture(null);
}

Q1. Why would TimeoutException not consider as a failure in the resilience4j ? Does Hystrix follows the same behaviour.

My requirement :

  1. I need CircuitBreaker to consider TimeoutExceptions as a failures with other already present exceptions.
  2. I need to to rethrow all exceptions(except BulkheadfullException and CallNotPermittedException) to the caller.

Reason -> MDC does not gets propagated to the fallbackMethod in case of TimeoutException and other RuntimeExceptions as they gets executed in a different thread pool than the parent threadpool in resilience4j. Because of this context information gets lost and logs in fallback method in case of TimeoutException does print the MDC variables. Checked the github issue for this, seems this is not yet solved.

I want to rethrow then in fallbackMethod, thus caller can catch and log them with the context information, hence no context info will be lost. Whereas in case of BulkheadfullException and CallNotPermittedException, fallback gets executed in the parent thread itself thus context information never gets lost here for these exceptions.

Is this possible in resilience4j?

0

There are 0 best solutions below