Polly超时政策说明

Lor*_*nzo 8 c# polly transient-failure

我正在尝试使timout政策正常运行。集成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 
        } );
Run Code Online (Sandbox Code Playgroud)

然后,我准备执行该策略

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

我从文档中得到的是,如果在timeoutPolicy.ExecuteAndCaptureAsync委托内部发生了超时,则Polly会自动调用onTimeout委托。对?

但是我的问题是:

  • 如果在执行委托内部发生异常会怎样?我应该把该波利结构包装在一个尝试中吗?
  • 当我分析策略结果时,如何理解超时是否发生?

mou*_*ler 6

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

正确的

如果在执行委托内部发生异常会怎样?

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

我应该把该波利结构包装在一个尝试中吗?

因为您使用的是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. */
);
Run Code Online (Sandbox Code Playgroud)

其次,作为在中调用cancel请求的替代方法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 
}
Run Code Online (Sandbox Code Playgroud)

更新:调用cancel请求将以两种方式工作-从onRetryAsync或内部,如上。顺序版本的优点是,如果取消请求失败并带有异常,则可以更轻松地推断出发生了什么。使用嵌套方法(在内部调用取消请求onRetryAsync),最终捕获到的异常policyResult.FinalException可能来自初始请求或取消请求-可能很难分辨出哪个。