在 Polly 中结合瞬态故障捕获和重新授权
Combining transient fault catching with reauthorization in Polly
我正在使用 Xamarin 编写移动应用程序,因此我需要一个重试网络请求的策略。我的应用程序调用的 API 提供了一个过期的 JWT,因此如果收到相关响应,我需要自动重新进行身份验证。这似乎对于 Polly 来说应该是微不足道的,Polly wiki 甚至说它是微不足道的,但我无法让它工作。
最终目标是:
- 如果出现网络问题,重试请求 4 次,间隔 2 秒
- 如果请求成功并且 returns 有一个有效的响应,那么就完全脱离 Polly,因为我们得到了我们需要的东西
- 如果请求成功但 returns 401(意味着我们需要重新验证):
- 使用保存的凭据并自动重新验证
- 如果凭据有效,则返回到重试网络故障的外部策略
- 如果凭据无效(身份验证端点 returns 401),则中断并注销用户
这是我的代码。如果响应成功,这将正常工作。它还会根据需要重试网络故障。问题是当收到 401 时,策略总是返回该响应。重新验证被调用并且 returns 成功,但 Polly 在那里中断 -- 原始请求未重试,并返回原始 401 响应。
// example
var result = await RetryPolicy.ExecuteAndCaptureAsync(() => _client.SendAsync(request));
// policies
public static PolicyWrap<HttpResponseMessage> RetryPolicy
{
get => WaitAndRetryPolicy.WrapAsync(ReAuthPolicy);
}
private static IAsyncPolicy WaitAndRetryPolicy
{
get => Policy
.Handle<WebException>()
.Or<HttpRequestException>()
.WaitAndRetryAsync(4, _ => TimeSpan.FromSeconds(2));
}
private static IAsyncPolicy<HttpResponseMessage> ReAuthPolicy
{
get => Policy
.HandleResult<HttpResponseMessage>(x => x.StatusCode == HttpStatusCode.Unauthorized)
.RetryAsync(retryCount: 1, onRetryAsync: (_, __) => App.CoreService.LogInWithSavedCredsAsync(true));
}
最终证明我的代码是正确的,我只是没有在 LogInWithSavedCredentials
函数中正确设置授权凭据。
我正在使用 Xamarin 编写移动应用程序,因此我需要一个重试网络请求的策略。我的应用程序调用的 API 提供了一个过期的 JWT,因此如果收到相关响应,我需要自动重新进行身份验证。这似乎对于 Polly 来说应该是微不足道的,Polly wiki 甚至说它是微不足道的,但我无法让它工作。
最终目标是:
- 如果出现网络问题,重试请求 4 次,间隔 2 秒
- 如果请求成功并且 returns 有一个有效的响应,那么就完全脱离 Polly,因为我们得到了我们需要的东西
- 如果请求成功但 returns 401(意味着我们需要重新验证):
- 使用保存的凭据并自动重新验证
- 如果凭据有效,则返回到重试网络故障的外部策略
- 如果凭据无效(身份验证端点 returns 401),则中断并注销用户
这是我的代码。如果响应成功,这将正常工作。它还会根据需要重试网络故障。问题是当收到 401 时,策略总是返回该响应。重新验证被调用并且 returns 成功,但 Polly 在那里中断 -- 原始请求未重试,并返回原始 401 响应。
// example
var result = await RetryPolicy.ExecuteAndCaptureAsync(() => _client.SendAsync(request));
// policies
public static PolicyWrap<HttpResponseMessage> RetryPolicy
{
get => WaitAndRetryPolicy.WrapAsync(ReAuthPolicy);
}
private static IAsyncPolicy WaitAndRetryPolicy
{
get => Policy
.Handle<WebException>()
.Or<HttpRequestException>()
.WaitAndRetryAsync(4, _ => TimeSpan.FromSeconds(2));
}
private static IAsyncPolicy<HttpResponseMessage> ReAuthPolicy
{
get => Policy
.HandleResult<HttpResponseMessage>(x => x.StatusCode == HttpStatusCode.Unauthorized)
.RetryAsync(retryCount: 1, onRetryAsync: (_, __) => App.CoreService.LogInWithSavedCredsAsync(true));
}
最终证明我的代码是正确的,我只是没有在 LogInWithSavedCredentials
函数中正确设置授权凭据。