Polly Timeout 乐观使用 HttpClientFactory。如何使用取消令牌?
Posted
技术标签:
【中文标题】Polly Timeout 乐观使用 HttpClientFactory。如何使用取消令牌?【英文标题】:Polly Timeout optimistic using HttpClientFactory. How can I use cancellation token? 【发布时间】:2022-01-20 04:55:35 【问题描述】:我想了解如何使用 HttpClientFactory
使用 Polly 实施乐观超时策略。
在网上的例子中,调用异步方法时使用超时策略能够传递取消令牌。但是如果我从配置服务中设置超时策略,如the guide 所示),我该如何管理取消令牌?
在示例代码中,来自链接的指南,我看到了:
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);
【问题讨论】:
我的帖子回答你的问题了吗? 【参考方案1】:您应该将chain 重试和超时策略合并为一个组合策略。
你有两个选择:
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 的超时确实支持 optimistic 和 pessimistic 超时。换句话说,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
,您可以在其中决定使用哪个版本。
【讨论】:
以上是关于Polly Timeout 乐观使用 HttpClientFactory。如何使用取消令牌?的主要内容,如果未能解决你的问题,请参考以下文章