简体   繁体   English

Polly超时政策说明

[英]Polly timeout policy clarification

I am trying to get the timout Policy to work correctly. 我正在尝试使timout政策正常运行。 I have the following requirement while integrating an api. 集成api时,我有以下要求。

  1. Create an http request to invoke endpoint1 and pass the transactionID and capture the result 创建一个http请求以调用Endpoint1并传递transactionID并捕获结果
  2. if the http request does not answer in 20 seconds then send a cancel request with the same transactionID and capture the result 如果http请求在20秒内未答复,则发送具有相同transactionID的取消请求并捕获结果

For this task I would like to use Polly which seems to me a fantastic component to help handling transient failures. 对于此任务,我想使用Polly,在我看来这是一个很棒的组件,可帮助处理瞬态故障。 However as I am very new to this technology I just want to be sure if I am implementing correctly. 但是,由于我对这项技术还很陌生,所以我只想确定我是否正确实施了该技术。

First of all I have created a timeout policy with Polly like this 首先,我像这样用Polly创建了一个超时策略

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

then after that 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 timout occurs inside the timeoutPolicy.ExecuteAndCaptureAsync delegate Polly automagically invoke the onTimeout delegate. 我从文档中得到的是,如果在timeoutPolicy.ExecuteAndCaptureAsync委托内部发生了超时,则Polly自动调用onTimeout委托。 Right? 对?

However my questions are: 但是我的问题是:

  • What happens if inside the execute delegate an exception occurs? 如果在执行委托内部发生异常会怎样? Should I wrap that polly construct in a try catch? 我应该把该波利结构包装在一个尝试中吗?
  • When I analyze the policy result how do I understand if the timeout has happened or not? 当我分析策略结果时,如何理解超时是否发生?

What I got from the documentation is that if a timeout occurs inside the ExecuteAndCaptureAsync delegate Polly automagically invoke the onTimeout delegate. 我从文档中得到的是,如果ExecuteAndCaptureAsync委托内部发生超时,Polly会自动调用onTimeout委托。 Right? 对?

Correct . 正确的

What happens if inside the execute delegate an exception occurs? 如果在执行委托内部发生异常会怎样?

Because you are using ExecuteAndCaptureAsync(...), the exception is placed in policyResult.FinalException . 因为您使用的是ExecuteAndCaptureAsync(...),所以将异常放置在policyResult.FinalException中

Should I wrap that polly construct in a try catch? 我应该把该波利结构包装在一个尝试中吗?

Because you are using ExecuteAndCaptureAsync(..), the exception is placed in policyResult.FinalException, so you don't need a try-catch. 因为您使用的是ExecuteAndCaptureAsync(..),所以该异常放置在policyResult.FinalException中,因此您不需要try-catch。

When I analyze the policy result how do I understand if the timeout has happened or not? 当我分析策略结果时,如何理解超时是否发生?

TimeoutPolicy throws TimeoutRejectedException on a timeout. TimeoutPolicy在超时时引发TimeoutRejectedException Because you are using ExecuteAndCaptureAsync(...), you should find that exception placed in policyResult.FinalException. 因为使用的是ExecuteAndCaptureAsync(...),所以应该在policyResult.FinalException中找到该异常。


A couple of further comments. 还有更多意见。 With TimeoutStrategy.Optimisitic , which is based on co-operative cancellation by CancellationToken , you should execute a delegate taking a cancellation token: 使用基于CancellationToken合作取消的 TimeoutStrategy.Optimisitic ,您应该执行一个带有取消令牌的委托:

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 invoking the cancel request inside the onRetryAsync: async ( context, timespan, task ) => { ... } , you have the option to make the code more sequential / less nested with a pattern like below: 其次,作为在onRetryAsync: async ( context, timespan, task ) => { ... }内调用取消请求的替代方法,您可以选择使代码更具顺序性/更少嵌套,如下所示:

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: Invoking the cancel request will work either way - from inside the onRetryAsync , or sequentially, as just above. 更新:调用取消请求将以两种方式工作-从onRetryAsync内部,或按顺序进行,如上。 An advantage of the sequential version is that it may make it easier to reason about what happens if the cancel request fails with an exception. 顺序版本的优点是,如果取消请求失败并带有异常,则可以更轻松地推断出发生了什么。 With the nested approach (cancel request invoked inside onRetryAsync ), an exception finally captured into policyResult.FinalException could come from either the initial request or the cancel request - and it may be hard to tell which. 使用嵌套方法(在onRetryAsync内部调用取消请求),最终捕获到policyResult.FinalException的异常可能来自初始请求或取消请求-可能很难分辨出哪个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM