11

我正在尝试使超时策略正常工作。我在集成 api 时有以下要求。

  1. 创建一个 http 请求来调用 endpoint1 并传递 transactionID 并捕获结果
  2. 如果 http 请求在 20 秒内没有响应,则发送具有相同 transactionID 的取消请求并捕获结果

对于这个任务,我想使用 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委托内部发生超时,Polly 会自动调用onTimeout委托。正确的?

但是我的问题是:

  • 如果在执行委托内部发生异常会发生什么?我应该将那个 polly 结构包装在 try catch 中吗?
  • 当我分析策略结果时,我如何了解是否发生超时?
4

1 回答 1

8

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

正确

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

因为您使用的是 ExecuteAndCaptureAsync(...),所以异常放置在 policyResult.FinalException 中

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

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

当我分析策略结果时,我如何了解是否发生超时?

TimeoutPolicy在超时时抛出 TimeoutRejectedException。因为您使用的是 ExecuteAndCaptureAsync(...),所以您应该发现该异常位于 policyResult.FinalException 中。


一些进一步的评论。使用基于合作取消的TimeoutStrategy.Optimisitic,您应该执行一个接受取消令牌的委托: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可能来自初始请求或取消请求 - 可能很难分辨是哪个。

于 2017-04-14T19:01:14.127 回答