在 Polly 重试策略中重用 HttpRequestMessage

2023-12-10

An HttpRequestMessage对象只能使用一次;未来尝试使用同一对象会抛出异常。我正在使用 Polly 重试一些请求,但遇到了这个问题。我知道如何克隆请求,有很多关于 SO 的示例,但我不知道如何克隆请求并在 Polly 重试时发送新请求。我怎样才能做到这一点?

这些是我的政策,供参考。这是一个 Xamarin 应用程序。我想在网络故障的情况下重试几次,如果响应未经授权,我想使用保存的凭据重新进行身份验证并再次尝试原始请求。

public static PolicyWrap<HttpResponseMessage> RetryPolicy
{
    get => WaitAndRetryPolicy.WrapAsync(ReAuthPolicy);
}

private static IAsyncPolicy WaitAndRetryPolicy
{
    get => Policy.Handle<WebException>().WaitAndRetryAsync(4, _ => TimeSpan.FromSeconds(2));
}

private static IAsyncPolicy<HttpResponseMessage> ReAuthPolicy
{
    get => Policy.HandleResult<HttpResponseMessage>(x => x.StatusCode == HttpStatusCode.Unauthorized)
        .RetryAsync((_, __) => CoreService.LogInWithSavedCredsAsync(true));
}

这不起作用,因为HttpRequestMessage重用,但这就是我想要实现的目标:

var request = new HttpRequestMessage(HttpMethod.Post, "some_endpoint")
{
    Content = new StringContent("some content")
};

request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

var policyResponse = await ConnectivityHelper.RetryPolicy
    .ExecuteAndCaptureAsync(() => _client.SendAsync(request)).ConfigureAwait(false);

// handle outcome

要抛出的代码InvalidOperationException if an HttpRequestMessage被重用是一个验证步骤HttpClient itself.

源代码链接

private static void CheckRequestMessage(HttpRequestMessage request)
{
    if (!request.MarkAsSent())
    {
        throw new InvalidOperationException(SR.net_http_client_request_already_sent);
    }
}

源代码链接

internal bool MarkAsSent()
{
    return Interlocked.Exchange(ref sendStatus, messageAlreadySent) == messageNotYetSent;
}

您可以将 polly 重试策略放在DelegatingHandler那行得通。它还提供了一个很好的 SoC(关注点分离)。如果将来你想not重试或更改重试行为,您只需删除DelegatingHandler或者改变它。注意废弃HttpRequestMessage和中间体HttpResponseMessage的对象。这是我使用的效果很好的一个(重试政策).

你的问题是一个开放式的,一般来说,这样对那些人来说并不好(see)。但就这样吧。我将其称为“反应式”方法,因为它一直使用令牌直到其 ttl,并获取新令牌。请注意,使用令牌 ttl 不会引发 401。

# gets token with its ttl
tokenService: iTokenService
    # use retry policy in DH here
    httpClient
    string getTokenAsync():
        # calls out for token
        # note: tokens typically have a ttl

# returns cached token till its tll, or gets a new token which is then cached
cachedTokenService: iCachedTokenService
    tokenCached
    tokenTtl
    iTokenService
    
    string getTokenAsync():
        # returns tokenCached or gets a new token based on ttl
        # note: fetches with some buffer before ttl to avoid failures on edge
        # note: buffer as 2x http timeout is good enough

# DH that adds the cached token to the outgoing "work" request
tokenHandler: delegatingHandler
    iCachedTokenService
    task<response> sendAsync(request, ct):
        # gets token, and adds token to request header

# worker service
workService: iWorkService
    # uses tokenHandler DH
    httpClient
    workAsync():
        # ...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Polly 重试策略中重用 HttpRequestMessage 的相关文章

随机推荐

  • 将两个数据框导出为一个 Excel 文件,并在指定位置的 pandas 中包含两张表

    我有两个数据框 如下所示 df1 Date t factor plan plan score 0 2020 02 01 5 NaN 0 1 2020 02 02 23 NaN 0 2 2020 02 03 14 start 0 3 2020
  • Javascript如何获取所选项目的ID

    我正在使用 Web2Py 将值列表发送到我的视图 我的 HTML 是这样的
  • Excel VBA 计算另一张工作表中的公式

    已解决 问题出在我的公式中 我使用 INDIRECT 引用单元格 当工作表不同时 该单元格不起作用 查看答案 我在一张纸上有一个公式 我想要做的是使用另一张纸上的公式 使用 eval 来评估该公式 然而 结果并不如预期 该公式似乎使用工作表
  • 使用 Chrome 查找 JavaScript 内存泄漏

    我创建了一个非常简单的测试用例 它创建一个 Backbone 视图 将处理程序附加到事件 并实例化一个用户定义的类 我相信 通过单击此示例中的 删除 按钮 所有内容都会被清理 并且不会出现内存泄漏 代码的 jsfiddle 在这里 http
  • 使用单例进行单元测试

    我已经使用 Visual Studio Team Edition 测试框架准备了一些自动测试 我希望其中一项测试按照程序中完成的正常方式连接到数据库 string r providerName ConfigurationManager Co
  • Delphi 字典和排序数据

    我的代码是 procedure TfrmSettings btnFillDictClick Sender TObject var Dict TDictionary
  • 在 Node.js 中复制 Java 密码哈希代码 (PBKDF2WithHmacSHA1)

    编辑 我的问题已更新 请查看这篇文章的底部以了解最新一期 我把剩下的留给那些想阅读整个故事的人 我一直致力于将一个小型 Java 应用程序转换为 Node js 大部分进展顺利 我必须查找大量 Java 函数来弄清楚它们的作用以及如何在 N
  • 获取mysql查询中一行的排名

    我使用此查询根据每个名字获得的票数为他们分配排名 但它返回错误 1248 每个派生表必须有自己的别名 这是我的代码 SELECT rownum rownum 1 AS rank name vote FROM table SELECT row
  • getJSON 不支持 async:false

    我下面有这段代码 它应该返回调用的结果 我需要同步执行此操作 以便我知道一切都很好 但它似乎不起作用 我究竟做错了什么 jQuery library http code jquery com jquery 1 9 1 min js func
  • Apache Beam -> BigQuery - 用于重复数据删除的 insertId 不起作用

    我使用 apache beam 和 google dataflow runner 将数据从 kafka 流式传输到 BigQuery 我想利用 insertId 进行重复数据删除 我在谷歌文档中找到了描述 但即使插入是在几秒钟之内发生的 我
  • 如何在 Google 地图中跟踪用户全天的位置?

    您如何跟踪用户一整天的位置 就像 Google 地图中的时间线一样 我有两个想法 例如 如果我有 200LatLng每天的价值 我如何通过所有这些LatLng值到谷歌地图作为点 我得到了一个谷歌文档参考因为我最多只能跟踪 10 个位置点 是
  • 如何在平板电脑/智能手机上启用立体声录音,尽管有两个内置麦克风,但仅产生单声道?

    到目前为止 我认为这是一个固件错误 但现在我刚刚发现第二个设备 它有两个内部麦克风胶囊 但只产生单声道信号 第一个是S2加GT I9105PAndroid 4 1 2 和现在HTC One M7 the Nexus 10Android 4
  • 使用servlet接收音频文件

    故事简介 我有一个 Servlet 它接收一个我无法读取的请求 getContentType audio x wav 我需要读取这一波并将其保存在服务器端 详细故事 我对 Flex javascript PHP 和 Python 一无所知
  • 重命名 s3 中的 Pyspark 输出文件

    我使用以下命令将 pyspark 数据帧保存到 s3 df coalesce 1 write partitionBy DATE format com databricks spark csv mode overwrite option he
  • 使用 glm 和二项式族更改参考组

    当我在 R 中使用由三个级别 较高 中 和 较低 组成的独立因子变量运行二项式回归时 我想使用以下命令更改参考类别relevel我收到此错误 Error in relevel ordered cbsnivcat3 Lower relevel
  • 删除括号前后的所有空格

    我想删除一个或多个空格before and after任何括号 下列的这个帖子PHP 的问题已通过以下正则表达式解决 lt 现在我想做同样的事情JavaScript但 Javascript 正则表达式引擎不具有与 PHP 相同的前瞻和后瞻功
  • 如何在 Android Lollipop 中保存 WebView 状态并恢复它?

    这个问题被问过多次 并且有曾经有效的答案 最近在文档中表示 出于安全原因 他们删除了此功能 webView状态只能恢复一些有限的东西 我尝试了多种方法来做到这一点 但每次刷新 webView 状态时 它都不会显示 webView 内容 我想
  • 如何使用 VSTS 扩展隐藏快速添加面板待办事项项?

    我想制作一个 VSTS 扩展 可以在加载页面时隐藏快速添加面板积压项目 快速添加面板待办事项 该扩展是针对 TFS 2015 更新 2 进行的 我已经运行了这段代码 但没有任何反应 动作 html
  • 在python beautifulsoup中从html中提取json

    我正在做一些爬虫 需要从用 bs4 做汤后返回的 div 中提取 json 内容 所以我现在得到了一个变量字符串 其中包含此文本变量 div class header product js header product div
  • 在 Polly 重试策略中重用 HttpRequestMessage

    An HttpRequestMessage对象只能使用一次 未来尝试使用同一对象会抛出异常 我正在使用 Polly 重试一些请求 但遇到了这个问题 我知道如何克隆请求 有很多关于 SO 的示例 但我不知道如何克隆请求并在 Polly 重试时