What's the correct way to modify the Duration Break on Polly? I know in the documentation they mention implementing (PolicyRegistry). Is there any example of this? I was implementing Polly CircuitBreaker in one WinService.
What's the correct way to modify the Duration Break on Polly? I know in the documentation they mention implementing (PolicyRegistry). Is there any example of this? I was implementing Polly CircuitBreaker in one WinService.
Circuit Breaker was not designed to use different sleep duration whenever it breaks.
In case of Retry you have the ability to provide a function, called sleepDurationProvider which is called by the policy to determine the actual sleep duration before issuing the next attempt.
So, in short by design it is not supported. I will show you a workaround, but I do not recommend to use it. I will provide a reasoning after the sample code.
For the sake of simplicity let's have the following method:
static int Probe()
{
Console.WriteLine("Probe has been called");
throw new NotSupportedException();
}
Let's define a helper method which increases the time period (>> sleep duration) each and every time whenever it is called:
static IEnumerable<TimeSpan> GetSleepDuration()
{
for (int i = 1; i < 10; i++)
{
yield return TimeSpan.FromSeconds(i);
}
}
sleepDurationProvider.Now it's time to define our Circuit Breaker policy:
var sleepDurationProvider = GetSleepDuration().GetEnumerator();
sleepDurationProvider.MoveNext();
var cb = Policy<int>
.Handle<NotSupportedException>()
.CircuitBreaker(1, TimeSpan.FromSeconds(0),
onBreak: (_, __) => {
Console.WriteLine(sleepDurationProvider.Current.TotalSeconds);
Thread.Sleep((int)sleepDurationProvider.Current.TotalMilliseconds);
sleepDurationProvider.MoveNext();
},
onReset: () => { },
onHalfOpen: () => Console.WriteLine("CB half opens"));
GetSleepDurationProbe call the CB will breakdurationOfBreak to zero because we will wait inside the onBreak << the workaroundIn order to ease our testing let's define a retry policy:
var retry = Policy<int>
.Handle<NotSupportedException>()
.WaitAndRetryForever(_ => TimeSpan.FromSeconds(0),
onRetry: (_, __) => Console.WriteLine("Retry is triggered"));
Probe's exceptionLet's wire up the policies and run the test:
Policy.Wrap(retry, cb).Execute(() => Probe());
The output will be:
Probe has been called
1
Retry is triggered
CB half opens
Probe has been called
2
Retry is triggered
CB half opens
Probe has been called
3
Retry is triggered
CB half opens
Probe has been called
4
Retry is triggered
CB half opens
Probe has been called
5
Retry is triggered
CB half opens
Probe has been called
6
Retry is triggered
CB half opens
Probe has been called
7
Retry is triggered
CB half opens
Probe has been called
8
Retry is triggered
CB half opens
Probe has been called
9
Retry is triggered
CB half opens
Probe has been called
9
...
Probe has been called and failedOpen to BrokenonBreak has been called, which block the execution for 1 secondPolicyWrap escalates the problem to RetryBroken to Hal-OpenProbe has been called and failedThe biggest problem with this solution that it is blocking. Unfortunately there is no async version of onBreak. (Retry does have onRetryAsync, in which you could use Task.Delay instead of Thread.Sleep)
The second problem is that it relies on the current implementation. This solution won't work if for example the onBreak is executed on a different thread and the exception is thrown immediately.