#指数退避 #重试 #退避 #指数

扎格卢斯

一个强大的退避处理库

2 个版本

0.1.1 2024 年 5 月 28 日
0.1.0 2024 年 5 月 22 日

#622 in 网页编程

MIT 许可证

22KB
266

扎格卢斯

扎格卢斯既是希腊小神祇再生的象征,也是他主演的电子游戏中的“游侠”精神。扎格卢斯是一个强大的重试、退避和日志记录库。

请注意,这个库还有一些功能尚未完善,需要编写示例和测试。

功能

  • async 异步 API
  • 运行时独立且无依赖
  • 日志记录
  • 在不可恢复的错误上短路
  • 间隔随机化
  • 无依赖!

用法

扎格卢斯的用户必须熟悉以下四个特质

  • BackoffStrategy:定义用于创建重试间隔的算法。
  • Randomizer:向由 BackoffStrategy 生成的间隔添加随机化。
  • BackoffLogger:公开用于记录尝试循环中遇到和尝试结束后遇到错误的日志方法。
  • BackoffHandler:生成(并暂停)由 Randomizer 随机化后的 BackoffStrategy 生成的时间。

首先创建一个 BackoffStrategy。这非常简单,只需要定义一个 limit() 来限制尝试迭代的次数,以及一个 interval() 方法来计算迭代之间的时间。

然后,创建一个 Randomizer。使用你选择的库、范围和随机源:实现者只需要公开一个 randomize 方法,该方法接受一个未随机化的 Duration 并返回一个新的具有所需变异性。

最后,BackoffLogger 的实现将确定如何在尝试循环中记录遇到和尝试结束后遇到的错误。

据此,每个实现都将传递给 BackoffHandler 或作为其成员进行组合,以生成所需的行为。

虽然 API 表面看起来很大,但这个 crate 的意图是作为一个构建块来覆盖大多数可能需要的重试实现的行为。为了处理这种复杂性,建议将 BackoffHandler 的实现隐藏在另一个(新)类型中,该类型具有 handle() 的参数,并为每个特定用例预定义并存储在其中。

常见问题解答

Q:如何限制重试间隔?

A: 从 BackoffStrategy::interval() 返回 None。跟踪时间的方法太多,以至于这个crate无法对此提出有意义的意见。相反,BackoffStrategy的实现者可以从第一次调用 interval() 开始跟踪时间,直到最终时间,当这个值超过开发人员感到舒适的某个最大值时,返回 None

虽然这意味着与时间请求相关的任何成本都是可选的,但它也使得取消超出给定 BackoffStrategy 分配时间的飞行中的请求成为不可能。

取消飞行中的请求超出了这个库的范围,应该在其他地方处理。

问:为什么 BackoffHandlerBackoffStrategy 是分开的特质?

A: 可能会方便让处理程序为不同的 fallible 实现不同的策略。比如说一个端点限制在一秒内的请求,另一个是两秒。对于另一个,性能约束可能要求尝试之间的间隔限制在500ms。

此外,如果 BackoffHandlerBackoffStrategy 是相同的,那么用来解决这些约束的策略将需要自己的随机数源:要么包含在其中(并通过 BackoffHandler::randomizer() 暴露),要么是程序的全球状态的一部分。这两种解决方案都对异步、高度并发的应用程序有负面的设计和性能影响。将这些特质分成两个部分,允许为每个端点轻松定制行为,而不必求助于每个端点的随机数源。

问:Zagreus 非常小(约200行代码),但API却很大/丑陋/难以控制。为什么?

A: 这个库旨在以轻量级和运行时独立的方式公开非常广泛的功能。将API整理得更加令人愉悦的责任在用户身上。不要期望你的类型的使用者直接与这些特质交互,相反,实现包装它们的类型,封装常见功能,只公开剩下的子集。

无运行时依赖

功能