Polly Timeout乐观地使用HttpClientFactory.如何使用取消令牌



我想了解如何使用HttpClientFactory实现Polly的乐观超时策略。

在网络上的示例中,当调用异步方法以传递取消令牌时,会使用超时策略。但是,如果我从配置服务中设置超时策略,如指南中所示(,我该如何管理取消令牌?

在示例代码中,从链接的指南中,我看到的是:

var timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(10); // Timeout for an individual try
serviceCollection.AddHttpClient("GitHub", client =>
{
client.BaseAddress = new Uri("https://api.github.com/");
client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
client.Timeout = TimeSpan.FromSeconds(60); // Overall timeout across all tries
})
.AddPolicyHandler(retryPolicy)
.AddPolicyHandler(timeoutPolicy);

您应该将重试和超时策略链接到一个组合策略中。

你有两个选择:

Wrap方法

.AddPolicyHandler(retryPolicy.Wrap(timeoutPolicy))
  • timeoutPolicy是内部策略,因此它分别应用于每次尝试
  • retryPolicy是外部策略,因此它是最重要的超时策略
  • 注意订购事项(我将在后面的部分中详细说明(

PolicyWrap

.AddPolicyHandler(Policy.Wrap(retryPolicy,timeoutPolicy))
  • 第一个论点是最外层的政策
  • 最后一个论点是最内在的政策

订购很重要

您应该意识到以下两种组合策略非常不同:

Policy.Wrap(retryPolicy,timeoutPolicy)
Policy.Wrap(timeoutPolicy, retryPolicy)
  • 在第一种情况下,您有一个本地超时,该超时适用于每次重试
  • 在第二种情况下,您有一个全局超时,它适用于整个重试活动

推进这一想法,您可以通过定义全局超时来避免设置HttpClient的Timeout属性:

var localTimeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(10);
var globalTimeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(60);
var resilientStrategy = Policy.Wrap(globalTimeoutPolicy, retryPolicy, localTimeoutPolicy);
serviceCollection.AddHttpClient("GitHub", client =>
{
client.BaseAddress = new Uri("https://api.github.com/");
client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
})
.AddPolicyHandler(resilientStrategy);

更新#1乐观超时

Polly的Timeout同时支持乐观和悲观超时。换句话说,Polly可以尝试取消那些预测CancellationToken(乐观(的待包装方法以及那些不预测(悲观(的方法。默认为前者。

在乐观的情况下,你有两个选择:

  • 让策略取消
await policy.ExecuteAsync(
async ct => await httpClient.SendAsync(..., ct),
CancellationToken.None);
  • 或者将其与您的自定义CTS组合/链接
await policy.ExecuteAsync(
async ct => await httpClient.SendAsync(..., ct),
cancellationSource.Token);

如果在启动过程中注册了命名/键入的客户端,则只能使用第一个选项。由于policy.ExecuteAsync将代表您(隐含地(调用。

如果您注册了一个类型化客户端,并在该客户端中定义了策略,那么您就是在显式调用ExecuteAsync,在这里您可以决定使用哪个版本。

相关内容

  • 没有找到相关文章

最新更新