通信にはエラーがつきもので、リトライ処理などするのが当たり前。
その当たり前を良い感じに実装できるPolly
というライブラリがあり、
これはHttpClientFactoryによく統合されているので使ってみましょう というお話。
使い方
HttpClientFactory用(前回記事)に加えて以下をNuget
する。
- Microsoft.Extensions.Http.Polly
Polly用のusingを追加して
using Polly;
using Polly.Extensions.Http;
ServiceCollection
にAddHttpClient()
するときに、名前付き もしくは 型指定 で行うと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とかできるのだろうか)
ネタ元のリンク
- ASP.NET Core で IHttpClientFactory を使用して HTTP 要求を行う | Microsoft Docs
- IHttpClientFactory を使用して回復力の高い HTTP 要求を実装する | Microsoft Docs
- IHttpClientFactory ポリシーと Polly ポリシーで指数バックオフを含む HTTP 呼び出しの再試行を実装する | Microsoft Docs
- Polly and HttpClientFactory | Polly GitHub