failsafe
failsafe copied to clipboard
Consider CircuitBreaker.withMaxConcurrency
This could place an easy cap on concurrent executions/requests through the circuit.
May need to use something like ExecutionRejectedException with max concurrency is reached.
@Spikhalskiy Can you help my understand your use case more for setting a max concurrency in a CircuitBreaker? When max concurrency is reached, you would be ok receiving an exception such as MaxConcurrencyException?
@Spikhalskiy Just pushed a change that allows you to limit max concurrency in the half-open state:
new CircuitBreaker()
.withSuccessThreshold(3)
.withMaxConcurrency(1);
Previously, withSuccessThreshold(3) would allow 3 concurrent executions when in the half-open state. Now we can limit that to 1 via withMaxConcurrency. We still need 3 successful executions, in this case, in order to close the circuit again, but we can restrict them to occurring one at a time.
Thoughts?
I think throwing exceptions is a bad idea, especially for a standalone usage. At least it's very expensive. I would prefer if after concurrency level reaching all methods in the Half Open state would work as for the Open state. Or this behavior could be configurable.
@Spikhalskiy Thanks - that's actually what it does currently - once max concurrent executions is hit while in half-open state, CircuitOpenException is thrown, which is the same thing that happens when you try an execution in the open state.
How I need to use this. CircuitBreaker is an underlying structure, which I want to notify about failure or success events, nothing more. After threshold of failure reaches it should be OPEN for configured interval and after than allow 1-2-3 times of service execution. In parallel or one by one, not significant. If it gets failure() for this calls it should put CircuitBreaker back to the Open state for configured interval, if requests are fine - put it to Close state.
@jhalterman So... for me it's bad behavior that I don't want to see in standalone mode at least. For example. I have 15 000 requests per second and I have limit for the Half Open state == 1. I would get 14999 exceptions per second only because I probe server right now. Too expensive and it's not an exceptional situation actually, it's just opened (in terms of CircuitBreaker) for now. We are closed for 1 request only and just opened for all others. Just from my usage point of view.
@Spikhalskiy Thanks for the info. I think we have 3-4 options when the circuit is in half-open state. We can allow the executions, we can block, we can schedule the executions (if an executor is configured) or we can throw an exception. If we're only allowing 1-3 executions, everything else either needs to block, be scheduled (which might throw an exception if the threadpool is full), or result in an exception. What do you think?