C# - HttpClientFactoryとPollyで回復力の高い何某

通信にはエラーがつきもので、リトライ処理などするのが当たり前。
その当たり前を良い感じに実装できるPollyというライブラリがあり、
これはHttpClientFactoryによく統合されているので使ってみましょう というお話。

使い方

HttpClientFactory用(前回記事)に加えて以下をNugetする。

  • Microsoft.Extensions.Http.Polly

Polly用のusingを追加して

using Polly;
using Polly.Extensions.Http;

ServiceCollectionAddHttpClient()するときに、名前付き もしくは 型指定 で行うとPolly処理を追加できる。

var services = new ServiceCollection();
// 名前付き
services.AddHttpClient("MyClient")
    // これでPolly
    .AddTransientHttpErrorPolicy(p => 
            p.WaitAndRetryAsync(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(3) }));

// 用意した Polly ポリシー
var myPolicy = HttpPolicyExtensions
                .HandleTransientHttpError()
                .WaitAndRetryAsync(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(3) });
// 型指定
services.AddHttpClient<MySerivce>()
    // これもPolly
    .AddPolicyHandler(myPolicy);
var provider = services.BuildServiceProvider();

この後、該当HttpClientで普通に処理するとPollyによりリトライ等が反映された処理をしてくれる。
型指定クライアントならDIされるし、名前付きクライアントならCreateClient()するときに名前を指定すると該当のものが取得できる。

var factory = provider.GetRequiredService<IHttpClientFactory>();
var client = factory.CreateClient("MyClient");

Pollyメモ

AddTransientHttpErrorPolicy()は以下三つをエラーとみなすポリシーがあらかじめ設定されており、引数のポリシーが追加される(たぶん)。

  • HttpRequestException
  • HTTP 5xx
  • HTTP 408

HttpPolicyExtensions.HandleTransientHttpError()は上記三つをエラーとみなすポリシーで、 AddPolicyHandler()は引数のポリシーがそのまま適用される。
(なので、サンプルコードの二つのクライアントは同じポリシーのはず)

ポリシーの書き方はExecute系をしない以外は普通のPollyと(たぶん)同じ。
(Execute系がどうなるのかは不明。例外Captureとかできるのだろうか)

ネタ元のリンク


See also