关于类似的关注,我有几个问题:我正在打电话给EmailServer,并使用Polly Policy进行WaitAndRetry。但是我希望重试仅针对特定的超时发生:5xx和429(并忽略其余的4xx)。
如何使其更优雅,同时涵盖所有5xx的可能性(因为下面的HttpStatusCode不能涵盖所有5xx的内容,也不能涵盖429)?
目前,我的代码如下(2个部分/选项):
private readonly HttpStatusCode[] _retryHttpStatusCodesList =
new[]
{
HttpStatusCode.InternalServerError,
HttpStatusCode.NotImplemented,
HttpStatusCode.BadGateway,
HttpStatusCode.ServiceUnavailable,
HttpStatusCode.GatewayTimeout,
HttpStatusCode.HttpVersionNotSupported,
HttpStatusCode.RequestTimeout,
HttpStatusCode.Unauthorized,
HttpStatusCode.RequestEntityTooLarge
};
选项1:
var waitAndRetryPolicy = Policy.Handle<Exception>()
.OrResult<HttpResponseMessage>(r => _retryHttpStatusCodesList.Contains(r.StatusCode))
.RetryAsync(2, (ex, retryCount) => { Console.WriteLine($"Retry count {retryCount}"); });
选项2(我无法弄清楚如何对StatusCode进行检查):
var waitAndRetryPolicy = Policy.Handle<Exception>()
.WaitAndRetryAsync(_maxRetries, retryAttempt => TimeSpan.FromMinutes(Math.Pow(_waitMinutes, retryAttempt)),
(ex, timeSpan) =>
{
Console.WriteLine($"Log Error {ex}");
});
SendGridClient client = new SendGridClient ();
var response = await policy.ExecuteAsync (() =>
client.SendEmailAsync(new SendGridMessage));
代替字典,您可以直接检查响应代码:
var retryPolicy = Policy
.Handle<Exception>()
.OrResult<HttpResponseMessage>(r =>
{
var statusCode = (int)r.StatusCode;
return (statusCode >= 500 && statusCode <= 599) || statusCode == 429;
})
.RetryAsync(2, (ex, retryCount) => { Console.WriteLine($"Retry count {retryCount}"); });
为回答您的评论,您只需将对RetryAsync(...)
的调用替换为WaitAndRetryAsync(...)
的代码:
var waitAndRetryPolicy = Policy
.Handle<Exception>()
.OrResult<HttpResponseMessage>(r =>
{
var statusCode = (int)r.StatusCode;
return (statusCode >= 500 && statusCode <= 599) || statusCode == 429;
})
.WaitAndRetryAsync(_maxRetries, retryAttempt => TimeSpan.FromMinutes(Math.Pow(_waitMinutes, retryAttempt)),
(ex, timeSpan) =>
{
Console.WriteLine($"Log Error {ex}");
});
[请记住,Polly
是流利的政策制定者。这意味着您正在调用的PolicyBuilder<T>
实例上的方法(例如.Handle<Exception>()
和.OrResult<HttpResponseMessage>()
)正在配置该构建器,以便使用诸如Policy<T>
或.WaitAndRetryAsync()
之类的调用来创建RetryAsync()
。配置方法不在乎要创建哪种策略,因此可以将它们用于any策略类型。