Polly: Overall timeout versus timeout-per-try; overall timeout cancelling waits-between-retries

Created on 18 Jul 2018  路  5Comments  路  Source: App-vNext/Polly

Hi guys,
I have a doubt regarding how to apply an overall timeout and a separate timeout for each individual try.
Given the below code, I would like to confirm if I'm using in the right way the policies for an overall and individual timeout.

var overalTimeoutPolicy = new IAsyncPolicy[] {
   Policy.TimeoutAsync(30, TimeoutStrategy.Pessimistic),
   Policy.Handle<SqlException>()
                .WaitAndRetryAsync(
                    retryCount,
                    retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))),
   Policy.Handle<SqlException>()
                .CircuitBreakerAsync(
                    exceptionsAllowedBeforeBreaking,
                    TimeSpan.FromMinutes(1))
};

var individualTimeoutPolicy = new IAsyncPolicy[] {
   Policy.Handle<SqlException>()
                .WaitAndRetryAsync(
                    retryCount,
                    retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))),
   Policy.TimeoutAsync(30, TimeoutStrategy.Pessimistic),
   Policy.Handle<SqlException>()
                .CircuitBreakerAsync(
                    exceptionsAllowedBeforeBreaking,
                    TimeSpan.FromMinutes(1))
};

Policy.Wrap(overalTimeoutPolicy).ExecuteAsync(action);
Policy.Wrap(individualTimeoutPolicy ).ExecuteAsync(action);

I appreciate in advance for your help!

how-to

Most helpful comment

@vany0114 That looks good:

  • If you place the timeout outside the retry in the PolicyWrap (that is, declared first), then the timeout applies as an overall timeout.
  • If you place the timeout inside the retry in the PolicyWrap (that is, declared after the retry within the wrap), then the timeout applies per try.

You can also do both in the same PolicyWrap: apply an overall timeout and a timeout per try. There is no barrier to using a TimeoutPolicy twice in the same PolicyWrap.

We discuss this in more depth, and show the flow through a PolicyWrap of this type, in the diagram in this part of the PolicyWrap wiki

All 5 comments

@vany0114 That looks good:

  • If you place the timeout outside the retry in the PolicyWrap (that is, declared first), then the timeout applies as an overall timeout.
  • If you place the timeout inside the retry in the PolicyWrap (that is, declared after the retry within the wrap), then the timeout applies per try.

You can also do both in the same PolicyWrap: apply an overall timeout and a timeout per try. There is no barrier to using a TimeoutPolicy twice in the same PolicyWrap.

We discuss this in more depth, and show the flow through a PolicyWrap of this type, in the diagram in this part of the PolicyWrap wiki

Another doubt is, what happens if my WaitAndRetry policy is configured for 3 attempts and the base of exponential backoff is 2, and my Timeout policy for every retry is, let's say 3 seconds, it means it will never reach even the second try because for the second attempt it will wait for 4 seconds.

If so, that means the Timeout policy would cancel the WaitAndRetry policy, so I should be consistent in the way I configure the policies, right?

Yes. If waits-and-retries inside a TimeoutPolicy mean the overall execution would take longer than the timeout allows, the timeout will time out the execution.

Specifically for the wait phase: both TimeoutStrategy.Optimistic and TimeoutStrategy.Pessimistic have the power to cancel a WaitAndRetry policy during the wait-before-retrying phase.

Thanks @reisenberger!

Thanks for the question @vany0114 . Added doco to the Timeout wiki specifically on this. Closing as think we are done, but reopen, or start a new issue, if further qs!

Was this page helpful?
0 / 5 - 0 ratings