Reputation: 877
I have the following Retry
and Circuit Breaker
policies:
var waitAndRetryPolicy = Policy
.Handle<Exception>(e => e is MycustomException)
.WaitAndRetryForeverAsync(
attempt => TimeSpan.FromMilliseconds(500),
(exception, calculatedWaitDuration) =>
{
_logger.LogInfo(exception.GetType().FullName);
_logger.LogInfo(".Log,then retry: " + exception.Message);
});
var circuitBreakerPolicy = Policy
.Handle<Exception>()
.CircuitBreakerAsync(
4,
TimeSpan.FromSeconds(10),
(ex, breakDelay) =>
{
_logger.LogError(".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!");
},
() => { _logger.LogError(".Breaker logging: Call ok! Closed the circuit again!"); },
() => { _logger.LogError(".Breaker logging: Half-open: Next call is a trial!"); }
);
return waitAndRetryPolicy.WrapAsync(circuitBreakerPolicy);
If I use my custom exception then my retry fails after logging the following:
It works fine if I use the standard Exception
type. Retry fires even when Circuit Breaker is open:
var waitAndRetryPolicy = Policy
.Handle<Exception>()
.WaitAndRetryForeverAsync(
attempt => TimeSpan.FromMilliseconds(500),
(exception, calculatedWaitDuration) =>
{
_logger.LogInfo(exception.GetType().FullName);
_logger.LogInfo(".Log,then retry: " + exception.Message);
});
Upvotes: 1
Views: 1243
Reputation: 22819
When the Circuit Breaker opens all the subsequent requests are rejected immediately with a BrokenCircuitException
. That means if the Retry fires during that time period when the Circuit Breaker is open then it will not handle it if you are looking for only the custom exception. That's why your resilient strategy ends there and throws the exception.
If you want to apply Retry for both (when the Circuit Breaker is open and when the Custom Exception has been thrown) then you have to use the Or<>
builder function.
var waitAndRetryPolicy = Policy
.Handle<Exception>(e => e is MycustomException)
.Or<BrokenCircuitException>
.WaitAndRetryForeverAsync(
attempt => TimeSpan.FromMilliseconds(500),
(exception, calculatedWaitDuration) =>
{
_logger.LogInfo(exception.GetType().FullName);
_logger.LogInfo(".Log,then retry: " + exception.Message);
});
Please bear in mind that the timing is important here. Your Circuit Breaker waits 10 seconds before it transition itself into Half-Open state. During that the Retry will try to perform several attempts but they will fail immediately. After each failed attempt it sleeps for 500ms. That means during 10 seconds (when the Circuit Breaker is open) the retry performs ~20 attempts with instant fail.
Upvotes: 1