Polly超时政策澄清

时间:2017-04-14 18:08:03

标签: c# polly transient-failure

我正在尝试让timout政策正常运作。 在集成api时我有以下要求。

  1. 创建一个http请求以调用endpoint1并传递transactionID并捕获结果
  2. 如果http请求在20秒内未回答,则发送具有相同transactionID的取消请求并捕获结果
  3. 对于这项任务,我想使用Polly,在我看来这是一个很好的组件,可以帮助处理瞬态故障。但是,由于我对这项技术很陌生,我只想确定我是否正确实施。

    首先,我已经像Polly一样创建了一个超时策略

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

    然后我准备执行政策

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

    我从文档中得到的结果是,如果在timeoutPolicy.ExecuteAndCaptureAsync委托内发生了一个timout,Polly会自动调用onTimeout委托。正确?

    但我的问题是:

    • 如果在执行委托中发生异常,会发生什么?我应该在try catch中包装那个polly构造吗?
    • 当我分析政策结果时,我如何理解超时是否已经发生?

1 个答案:

答案 0 :(得分:4)

  

我从文档中得到的是,如果在内部发生超时   ExecuteAndCaptureAsync委托Polly自动调用   onTimeout委托。正确?

Correct

  

如果在执行委托内发生异常,会发生什么?

因为您使用的是ExecuteAndCaptureAsync(...),所以例外是placed in policyResult.FinalException

  

我应该在try catch中包装那个polly构造吗?

因为您使用的是ExecuteAndCaptureAsync(..),所以异常会放在policyResult.FinalException中,因此您不需要try-catch。

  

当我分析政策结果时,我如何理解超时是否已经发生?

TimeoutPolicy throws TimeoutRejectedException超时。因为您正在使用ExecuteAndCaptureAsync(...),所以您应该在policyResult.FinalException中找到该异常。

进一步评论。使用TimeoutStrategy.Optimisitic based on co-operative cancellation by CancellationToken,您应该执行取消令牌的委托:

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. */
);

其次,作为在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 
}

更新:调用取消请求将以任一方式工作 - 从onRetryAsync内部,或顺序,如上所述。顺序版本的一个优点是,如果取消请求因异常而失败,它可以更容易推断出现的情况。使用嵌套方法(在onRetryAsync中调用取消请求),最终捕获到policyResult.FinalException的异常可能来自初始请求或取消请求 - 并且可能很难分辨哪个。