在 Polly 重试尝试中获取完整的 URI?

Roy*_*mir 4 c# dotnet-httpclient .net-core polly retry-logic

我正在使用 Polly 重试 HttpClient 尝试:

\n
        services.AddHttpClient<JoinPackageApiClient>(jp => { jp.BaseAddress = new Uri(appSettings.JoinPackageWS.BaseUrl); })\n            .AddPolicyHandler(GetRetryPolicy(appSettings, serviceProvider))\n
Run Code Online (Sandbox Code Playgroud)\n

哪里 GetRetryPolicy

\n
 private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy(AppSettings appSettings, ServiceProvider serviceProvider)\n        {\n            return HttpPolicyExtensions\n                .HandleTransientHttpError()\n                .OrResult(msg => msg.StatusCode != HttpStatusCode.OK)\n                .Or<TimeoutRejectedException>()\n                .Or<TaskCanceledException>()\n                .Or<OperationCanceledException>()\n\n                .WaitAndRetryAsync(appSettings.PollySettings.RetryAttempts, (retryAttempt, c) =>\n                {\n\n                 return TimeSpan.FromSeconds(2);\n                }, onRetry: (response, delay, retryCount, context) =>\n                {\n\n                   //\xe2\x96\x88how can I access the full(!) HttpClient's URI here ?\n                   //e.g. : https://a.com/b/c?d=1\n               \n                });\n        }\n
Run Code Online (Sandbox Code Playgroud)\n

问题:

\n

查看该onRetry参数,我想在该onRetry部分中记录完整的 URL 尝试。

\n

我怎样才能获得该部分的完整 URI?

\n

Pet*_*ala 6

当我在评论中指出这是不可能的时,我错了。

在此输入图像描述

我必须纠正自己:是的,这是可行的,而且实际上很容易。:)

您需要做的就是使用不同的重载AddPolicyHandler

public static IHttpClientBuilder AddPolicyHandler (this IHttpClientBuilder builder, Func<IServiceProvider,HttpRequestMessage,IAsyncPolicy<HttpResponseMessage>> policySelector);
Run Code Online (Sandbox Code Playgroud)

因此,每当您调用时,AddPolicyHandler您都必须提供一个函数,该函数

所以,你必须像这样修改注册码:

services.AddHttpClient<JoinPackageApiClient>(jp => ...)
        .AddPolicyHandler((provider, request) => GetRetryPolicy(appSettings, provider, request));
Run Code Online (Sandbox Code Playgroud)

GetRetryPolicy这样的方法:

private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy(
    AppSettings appSettings,
    IServiceProvider serviceProvider, 
    HttpRequestMessage request)
   => HttpPolicyExtensions
        .HandleTransientHttpError()
        ...
        .WaitAndRetryAsync(appSettings.PollySettings.RetryAttempts, 
        (_, __) => TimeSpan.FromSeconds(2),
        (response, delay, retryCount, context) =>
        {
            var url = request.RequestUri;
            // ...
        });
Run Code Online (Sandbox Code Playgroud)

好消息是,每当您发出新请求时,URL 都会发生变化。(在我的测试客户端中,我已将 BaseAddress 设置为http://httpstat.us)当我运行此测试时

await client.GetAsync("/200");
try
{
    await client.GetAsync("/401");
}
catch { }
await client.GetAsync("/403");
Run Code Online (Sandbox Code Playgroud)

然后重试触发 4 次(401 为 2 次,403 为 2 次)。收到onRetry了相关信息HttpRequestMessage,所以记录是准确的。