Resilience4j version: 1.3.1
Java version: 1.8
I just want to know the circuit breakers status. ex) is open or half-open and can call backend).
so I used tryAcquirePermission(). but I missed the comment below.
* Important: Make sure to call onSuccess or onError after the call is finished.
* If the call is canceled before it is invoked, you have to release the permission again.
so everything is looks fine until the circuit breaker is half-open.
when circuit breaker is half-open, to call tryAcquirePermission is effect permittedNumberOfCallsInHalfOpenState. ( Using this method affects this property.)
if call count reached permittedNumberOfCallsInHalfOpenState, circuit breaker stuck half-open
I think need to make a method to check to call permitted a backend service.
If possible, I want to make it.
Hi,
you can use CircuitBreakerUtil.isCallPermitted(circuitBreaker) for this.
@RobWin I used CircuitBreakerUtil.isCallPermitted(circuitBreaker) :)
but I found some issue.
see the code below
fun call(cnt: Int): Mono<Boolean> {
if (!CircuitBreakerUtil.isCallPermitted(circuitBreaker)) { // 1) check to call permitted
return true.toMono() // In production, we returns message for user. for example a can not use the feature, please try later
}
return Mono.just(throwEnable) // 2) if call permitted, call backend.
.flatMap {
if (it) {
Mono.error(ApiException(ErrorCd.INTERNAL_ERROR)) // 3) if backend throw exception and reached failed count, the circuit breaker is OPEN.
} else {
it.toMono()
}
}
.transform(CircuitBreakerOperator.of(circuitBreaker))
.onErrorResume {
Mono.empty()
}
.doOnSubscribe {
log.info("cnt: $cnt circuit breaker status: ${circuitBreaker.state}")
}
}
if the circuit breaker is OPEN, it never changes state to half-open.
because don't call tryAcquirePermission().
What should I do in this case?
Hi @chayu07
There is automaticTransitionFromOpenToHalfOpenEnabled property.
If set to true, CircuitBreaker will automatically transition from open to half-open state.
This is not how you should use the CircuitBreaker. The exception from the CircuitBreaker tells you that it is open, just map the exception to a proper response to the user. Please don't do it that way.
There is usually no need to use this CircuitBreakerUtil class.
You can create a method like this:
private <T> Mono<T> executeWithFallback(Mono<T> publisher, Function<Throwable, Mono<T>> fallback){
return publisher
.transform(TimeLimiterOperator.of(timeLimiter))
.transform(CircuitBreakerOperator.of(circuitBreaker))
.onErrorResume(TimeoutException.class, fallback)
.onErrorResume(CallNotPermittedException.class, fallback);
}
The fallback can be your message to the user.
Mono<T> result = executeWithFallback(() -> yourService.method(), () -> Mono.empty());
Most helpful comment
You can create a method like this:
The fallback can be your message to the user.