Сочетание переходного поиска неисправностей с повторной авторизацией в Polly - PullRequest
0 голосов
/ 30 мая 2018

Я пишу мобильное приложение с помощью Xamarin, поэтому мне нужна политика для повторения сетевых запросов.API, который вызывает мое приложение, предоставляет JWT, срок действия которого истекает, поэтому мне нужно автоматически повторно подтвердить подлинность, если соответствующий ответ получен.Похоже, это должно быть тривиально с Полли, и вики Полли даже говорят, что это тривиально, но я не могу заставить его работать.

Конечная цель:

  • Повторитьзапрашивает 4 раза, с интервалом в 2 секунды, в случае проблемы с сетью
  • Если запрос когда-либо завершится успешно и вернёт правильный ответ, то полностью откажется от Полли, потому что мы получили то, что нам нужно
  • Еслизапрос успешно выполняется, но возвращает 401 (что означает, что нам нужно повторно подтвердить подлинность):
    • Использовать сохраненные учетные данные и автоматически выполнять повторную проверку подлинности
    • Если учетные данные были действительными, вернитесь к внешней политике повторных попыток при сбоях сети
    • Если учетные данные недействительны (конечная точка аутентификации возвращает 401), тогда прервите и выйдите из системы пользователя

Вот мой код.Если ответ успешен, это работает правильно.Это также повторяет по мере необходимости для сбоев сети.Проблема заключается в том, что при получении 401 этот ответ всегда возвращается из политики.Повторная проверка подлинности вызывается и успешно возвращается, но Полли прерывается там - исходный запрос не повторяется, и возвращается исходный ответ 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));
}

1 Ответ

0 голосов
/ 31 мая 2018

Оказывается, мой код был верным в конце концов, я просто не правильно установил полномочия авторизации в своей функции LogInWithSavedCredentials.

...