带有 Polly 超时策略的 HttpClientFactory 似乎不起作用



我正在尝试使用新的.NET Core 2.1 HttpClientFactory实现Polly Timeout策略;然而,我似乎无法让超时发生。

我的ConfigureServices:

// Configure polly policies
TimeoutPolicy<HttpResponseMessage> timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(5, TimeoutStrategy.Pessimistic);
// Configure platform service clients
services.AddHttpClient<IDiscoveryClient, DiscoveryClient>()
.AddPolicyHandler(timeoutPolicy);

我在DiscoveryClient:中的POST方法

public async Task<TResponse> PostXMLAsync<TResponse, TPostData>(string url, TPostData postData)
where TResponse : ClientResponse
where TPostData : ClientPostData
{
HttpResponseMessage response = await httpClient.PostAsXmlAsync(url, postData);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsAsync<TResponse>();
}

不幸的是,调用在默认的100秒之后超时,而不是在Polly策略中定义的5秒之后。

你觉得我做错了什么吗?

首先让我们定义一个模拟服务器,它在100秒后以500响应:

const string address = "http://localhost:9000";
var delay = TimeSpan.FromSeconds(100);
var server = WireMockServer.Start(new WireMockServerSettings { Urls = new[] { address } });
server
.Given(Request.Create().WithPath("/").UsingPost())
.RespondWith(Response.Create().WithDelay(delay).WithStatusCode(500));

我用过WireMock.Net。

现在,让我们看看IDiscoveryClientDiscoveryClient:

interface IDiscoveryClient
{
Task<TResponse> SendRequest<TResponse, TPostData>(string url, TPostData data);
}
class DiscoveryClient : IDiscoveryClient
{
private readonly HttpClient httpClient;
public DiscoveryClient(HttpClient httpClient) => this.httpClient = httpClient;
public async Task<TResponse> SendRequest<TResponse, TPostData>(string url, TPostData data)
{
var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8);
var response = await httpClient.PostAsync(url, content);
response.EnsureSuccessStatusCode();
var rawData = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<TResponse>(rawData);
}
}
class TestRequest { public string Content { get; set; } }
class TestResponse { public string Data { get; set; } }

我使用了json而不是xml,但从问题的角度来看,这并不重要。

最后,让我们连接DI并发出一个请求:

AsyncTimeoutPolicy<HttpResponseMessage> timeoutPolicy =
Policy.TimeoutAsync<HttpResponseMessage>(5, TimeoutStrategy.Pessimistic);
IServiceCollection services = new ServiceCollection();
services.AddHttpClient<IDiscoveryClient, DiscoveryClient>()
.AddPolicyHandler(timeoutPolicy);
ServiceProvider serviceProvider = services.BuildServiceProvider();
var client = serviceProvider.GetService<IDiscoveryClient>();
Stopwatch sw = Stopwatch.StartNew();
try
{
TestResponse res = await client.SendRequest<TestResponse, TestRequest>(address, new TestRequest { Content =  "Test"});
}
catch (TimeoutRejectedException ex)
{
sw.Stop();
Console.WriteLine(sw.Elapsed);
}

打印的输出将是这样的:

00:00:05.0296804

好的是,它也适用于OptimisticPessimistic策略。

相关内容

  • 没有找到相关文章

最新更新