Explanatory policy

I am trying to get the scheduling policy to work correctly. I have the following requirement while integrating api.

  • Create an HTTP request to call endpoint1 and pass the transaction id and write the result
  • if the HTTP request does not respond in 20 seconds, then send a cancellation request with the same transaction ID and record the result

For this task, I would like to use Polly, which seems like a fantastic component to me to help handle transient faults. However, since I am very new to this technology, I just want to be sure I am implementing it correctly.

First of all, I created a timeout policy with Polly like this

var timeoutPolicy =
    Policy.TimeoutAsync(
        TimeSpan.FromSeconds( 20 ),
        TimeoutStrategy.Optimistic,
        async ( context, timespan, task ) => {
            //write here the cancel request 
        } );

      

after which I am ready to execute the policy

var policyResult = await timeoutPolicy.ExecuteAndCaptureAsync( async () => {
    //make here the request 1
} );

      

What I got from the documentation is that if a timeout occurs timeoutPolicy.ExecuteAndCaptureAsync

automatically in a Polly delegate, you automatically include the delegate onTimeout

. Right?

However my questions are:

  • What happens if an exception is thrown inside the execute delegate? Should I wrap this political construct in a try catch?
  • When I analyze the result of the policy, how can I tell if the waiting time has occurred or not?
+3


source to share


1 answer


What I got from the documentation is that if a timeout happens inside the ExecuteAndCaptureAsync Delegate, Polly will automatically fire the onTimeout delegate. Right?

Correct .

What happens if an exception is thrown inside the execute delegate?

Since you are using ExecuteAndCaptureAsync (...) the exception is thrown in policyResult.FinalException .

Should I wrap this polly construct in a try catch?

Since you are using ExecuteAndCaptureAsync (..) the exception is being thrown in policyResult.FinalException, so you don't need try-catch.

When I analyze the result of the policy, how can I tell if the waiting time has occurred or not?



TimeoutPolicy throws TimeoutRejectedException on timeout. Since you are using ExecuteAndCaptureAsync (...) you should find this exception thrown in policyResult.FinalException.


A few further comments. From TimeoutStrategy.Optimisitic

, which based on shortening the cooperation toCancellationToken

, you must implement a delegate that accepts a cancellation token:

var policyResult = await timeoutPolicy.ExecuteAndCaptureAsync(async (ct) => {
    //make request 1, in a form which responds to the cancellation token ct
}, userCancellationToken /* CancellationToken.None is acceptable. Polly will merge its timing-out CancellationToken into ct, during policy execution. */
);

      

Second, as an alternative to calling the cancellation request internally onRetryAsync: async ( context, timespan, task ) => { ... }

, you can make the code more consistent / less nested with a pattern like below:

var policyResult = await timeoutPolicy.ExecuteAndCaptureAsync(async (ct) => {
    //make request 1, in a form which responds to the cancellation token ct
}, CancellationToken.None);

if (policyResult.Outcome == OutcomeType.Failure && policyResult.FinalException is TimeoutRejectedException)
{
    //write here the cancel request 
}

      

UPDATE: Calling the cancel request will work either way - from within onRetryAsync

or sequentially, like just above. The advantage of the sequential version is that it can make it easier to reason about what happens if the cancellation request fails with an exception. With a nested approach (a cancellation request being onRetryAsync

thrown internally ), the exception finally caught in policyResult.FinalException

can come from either the original request or the cancellation request and it can be tricky to determine which one.

+2


source







All Articles