How to execute multiple policies (or combine them into a single one)?
For example I have:
var policy1 = Policy.Handle<DivideByZeroException>().WaitAndRetry(5));
var policy2 = Policy.Handle<StackOverflowException>().RetryForever();
How to apply them to one method at the same time?
As of Polly v5.0, there's a new PolicyWrap class, which let you combine multiple policies.
var policy1 = Policy.Handle<DivideByZeroException>().WaitAndRetry(3, i => TimeSpan.FromSeconds(1));
var policy2 = Policy.Handle<StackOverflowException>().RetryForever();
PolicyWrap policyWrap = Policy.Wrap(policy1, policy2);
policyWrap.Execute(someGreatAction);
                        There are several ways to combine two policies. Let me list all the different options for the sake of completeness. I will add recommendations for each: when to use it and when to avoid it
ExceptionDispatchInfo edi = null;
int retryCounter = 0;
var combinedPolicy = Policy
       .Handle<DivideByZeroException>()
       .Or<StackOverflowException>()
       .WaitAndRetry(CalculateSleep());
combinedPolicy.Execute(() => {
    try
    {
        //User code...
        throw new DivideByZeroException();
    }
    catch (Exception ex)
    {
        edi = ExceptionDispatchInfo.Capture(ex);
        edi.Throw();
    }
});
IEnumerable<TimeSpan> CalculateSleep()
{
    while (true)
    {
        var wasItADivideByZero = edi.SourceException is DivideByZeroException;
        var attempt = retryCounter++;
        if (wasItADivideByZero)
        {
            if (attempt > 3) break;
            yield return TimeSpan.FromSeconds(1);
        }
        yield return TimeSpan.FromSeconds(0);
    }
}
WaitAndRetry does not have an overload where you don't have to specify the retryCount but you can access the thrown exception inside the sleepDurations
retryCount + sleepDurationProvider (from where you can access the exception) or use sleepDurations
ExceptionDispatchInfo to capture the thrown exception and access it inside our custom CalculateSleep methodvar combinedPolicy = Policy
       .Handle<DivideByZeroException>()
       .Or<StackOverflowException>()
       .WaitAndRetry(3,
       (_, ex, __) => TimeSpan.FromSeconds(ex is DivideByZeroException ? 1 : 2),
       (_, __, ___, ____) => { });
policy1.Execute(() =>
{
    policy2.Execute(() =>
    {
        //User code
    });
});
OR
policy2.Execute(() =>
{
    policy1.Execute(() =>
    {
        //User code
    });
});
policy1.Execute(policy2.Execute(UserCode()));
Wrap instance methodvar combinedPolicy = policy1.Wrap(policy2);
combinedPolicy.Execute(UserCode());
OR
var combinedPolicy = policy2.Wrap(policy1);
combinedPolicy.Execute(UserCode());
combinedPolicy's type is PolicyWrap, which implements the ISyncPolicy interface as wellvar combinedPolicy = globalTimeout.Wrap(retry).Wrap(circuitBreaker).Wrap(localTimeout);
void and another policy for TResult then the system tries to act smart
combinedPolicy is now PolicyWrap<string>
var policy1 = Policy.Handle<DivideByZeroException>().WaitAndRetry(3, i => TimeSpan.FromSeconds(1));
var policy2 = Policy<string>.Handle<StackOverflowException>().RetryForever();
var combinedPolicy = policy1.Wrap(policy2);
string? result = combinedPolicy.Execute(() => "dummy response");
Wrap static methodvar combinedPolicy = Policy.Wrap(policy2, policy1);
OR
var combinedPolicy = Policy.Wrap(policy2, policy1);
ISyncPolicy or ISyncPolicy<TResult> policiesISyncPolicy and a ISyncPolicy<string> policies because all policies should have the same typevar combinedPolicy = Policy.Wrap<HttpResponseMessage>(globalTimeout,retry,circuitBreaker,localTimeout);
TResult and one or more void
TResult and one or more void
TResult1 and TResult2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With