繁体   English   中英

在 HttpStatusCode.Unauthorized 之后使用 Polly 重试

[英]Using Polly to retry after HttpStatusCode.Unauthorized

我正在调用外部 API 并希望处理调用返回Unauthorized HttpResponseMessage的事件。 发生这种情况时,我想刷新访问令牌并再次拨打电话。

我正在尝试将Polly与以下代码一起使用:

    public async Task<HttpResponseMessage> MakeGetRequestAsync()
    {
        var retryPolicy = Policy
            .HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Unauthorized)
            .Retry(1, (exception, retryCount) =>
            {
                RefreshAccessToken();
            });

        var result = await retryPolicy.ExecuteAsync(() => CallApiAsync());

        return result;
    }


    private async Task<HttpResponseMessage> CallApiAsync()
    {
        var url = Options.ResourceSandboxUrl;

        var httpClient = new HttpClient();
        SetRequestHeaders(httpClient);
        var response = await httpClient.GetAsync(url);

        response.StatusCode = HttpStatusCode.Unauthorized;
        return response;
    }

我在ExecuteAsync语句和DoSomethingAsync中设置断点 - 当我跨过ExecuteAsync时,不会调用DoSomethingAsync并将控制权返回给调用 MakeGetRequestAsync 的MakeGetRequestAsync

我不明白为什么不调用DoSomethingAsync - 任何人都可以帮助我实现我想要实现的目标吗?

我查看了有关 Stack Overflow 的 Polly 文档和 Polly 问题,但我不知道发生了什么......

要使用ExecuteAsync()您必须将策略声明为.RetryAsync(...) ,而不是.Retry(...)

如果您的实际代码与上面的代码示例完全相同,则.ExecuteAsync(...)将因.Retry(...) [同步​​策略] 和.ExecuteAsync(...) [异步执行]。 由于抛出此异常, CallApiAsync()确实从未调用CallApiAsync() 调用MakeGetRequestAsync()时,您应该能够看到抛出的异常

整体代码方法看起来不错:这种重试刷新身份验证是Polly 的一种经过验证的模式

我正在回答这个老问题只是为了指出官方记录此模式的 Polly wiki 页面:

重试刷新授权

特别是这是建议的代码片段:

var authorisationEnsuringPolicy = Policy
    .HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Unauthorized) 
    .RetryAsync(
       retryCount: 1, // Consider how many retries. If auth lapses and you have valid credentials, one should be enough; too many tries can cause some auth systems to blacklist. 
       onRetryAsync: async (outcome, retryNumber, context) => FooRefreshAuthorizationAsync(context), 
      /* more configuration */); 

var response = authorisationEnsuringPolicy.ExecuteAsync(context => DoSomethingThatRequiresAuthorization(context), cancellationToken);

FooRefreshAuthorizationAsync(...)方法可以获取新的授权令牌并将其传递给使用Polly.Context通过策略执行的委托。

我可能会迟到,但我在这里为未来的读者留下一个帖子。 我为此刷新令牌创建了两个略有不同的解决方案,但存在重试问题。

重试策略、委托处理程序和自定义异常

在 401 的情况下刷新令牌

重试策略、委托处理程序和 Polly.Context

此版本以不同的方式分离职责:

刷新令牌

这就是 async await 在 .net 中的工作方式,当您的代码执行达到await ,会发生两件事

  1. 您的代码的当前线程应该释放以使您的代码异步,这意味着您的方法应该返回

  2. 当您等待的任务完成时,您的方法应该从以前的位置继续

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM