1

私たちは 429 の HTTP 例外 (SharePoint online または Microsoft Graph からのもの) に苦しんでおり、これを処理するために Polly と Castle.Windsor を活用したいと考えています。

私のコードは(抜粋)

Castle.Windsor コンテナへの Polly の登録:

_container.Register(Component.For<IRepository>()
            .ImplementedBy<Repository>()
            .DependsOn(Dependency.OnValue<ImportSettings>(_importSettings))
            .Interceptors(InterceptorReference.ForKey("throttle")).Anywhere
            .LifestyleTransient());

 _container.Register(Component.For<WaitAndRetryInterceptor<WebException>>().LifeStyle.Singleton
    .Named("throttle"));

私のポリーのもの:

 public class WaitAndRetryInterceptor<T> : IInterceptor where T : WebException
    {
        private readonly RetryPolicy _policy;

        public void Intercept(IInvocation invocation)
        {
            var dictionary = new Dictionary<string, object> {{"methodName", invocation.Method.Name}};

            _policy.Execute(invocation.Proceed, dictionary);
        }

        public WaitAndRetryInterceptor()
        {
            _policy =
                Policy
                    .Handle<T>()
                    .WaitAndRetry(new[]
                    {
                        TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(32), TimeSpan.FromSeconds(64),
                        TimeSpan.FromSeconds(128), TimeSpan.FromSeconds(256), TimeSpan.FromSeconds(512)
                    });
        }
    }

したがって、この実装は私のニーズをカバーしていますが、非常に保守的です。そこで、スローされた 429 例外の直接サポート、特にReply-Afterサーバーから利用可能なヘッダーのサポートを実装しようとしました。

このhttps://github.com/App-vNext/Polly/issues/414から、 を使用するオーバーロードの 1 つのサポートを実装する必要があることがわかりましたsleepDurationProviderが、コードを正しく取得する際に問題が発生しています。

私の実装はこれでした:

_policy =
  Policy
    .Handle<HttpRequestException>()
    .OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Accepted) //needs to be changed to 429
    .WaitAndRetryAsync(
        retryCount: 3,
        sleepDurationProvider: (retryCount, response) =>
        {
            return getServerWaitDuration(response);
        })
;

getServerWaitDuration単純にTimeSpan

private TimeSpan getServerWaitDuration(DelegateResult<HttpResponseMessage> response)
{
    return TimeSpan.Zero;  //not actual code ;-)
}

アイデアは、サーバーからの応答のヘッダーを見て、タイムスパンをsleepDurationProvider.

ただし、を構成する行からエラーが発生しますsleepDurationProvider(retryCount, response)は「互換性のない匿名関数の署名」であると言われました

ここで明らかな何かが欠けているように感じます。しかし、なぜ?オブジェクトにアクセスして期間responseを抽出するにはどうすればよいですか?Retry-After

4

1 に答える 1