#retry #macro #tokio #async-std #sync #async-await #function

重试

带有宏和函数的通用重试库,适用于 Rust

1 个不稳定版本

0.1.0 2023 年 12 月 19 日

750Rust 模式

Download history 4/week @ 2024-04-01 24/week @ 2024-04-29 56/week @ 2024-05-06 70/week @ 2024-05-13 64/week @ 2024-05-20 67/week @ 2024-05-27 119/week @ 2024-06-03 162/week @ 2024-06-10 149/week @ 2024-06-17 289/week @ 2024-06-24

每月 723 次下载

MIT/Apache

24KB
419

retrying

通用重试库,用 Rust 编写,用于简化将重试行为添加到 Rust 函数的任务。
支持同步和异步(tokioasync-std)函数。

[dependencies]
retrying = "0.1.0"

retrying 的主要公共接口是 retrying::retry 宏。

#[retrying::retry]
fn my_function(){}

此宏具有许多配置选项,允许开发者编写容错函数而无需考虑重试功能的实现。
⚠️ 宏生成代码并添加前缀为 retrying_ 的变量到代码中。为了避免变量冲突,请不要在带有 retry 宏的函数中使用具有此前缀的变量。

配置选项

  • 停止

本节描述了指定何时应停止方法执行重试的配置选项。

配置选项 操作系统环境 默认 描述
stop=attempts(u32) {PREFIX}__RETRYING__STOP__ATTEMPTS - 重试次数
stop=delay(f32) {PREFIX}__RETRYING__STOP__DELAY - 重试周期(秒)

可以通过使用 运算符(|)组合多个 stop 条件。例如,配置

#[retrying::retry(stop=(attempts(10)|delay(60.8)))]
fn my_function(){}

表示函数应重试 10 次,但在 60 秒后不进行新的尝试。

如果未指定停止配置,则重试宏会不断尝试,直到函数完成且没有错误。

  • 等待

本节描述了指定每次尝试之间延迟的配置选项。

配置选项 操作系统环境 默认 描述
wait=fixed(f32) {PREFIX}__RETRYING__WAIT__FIXED 0 重试之间的秒数
wait=random(min=f32, max=f32) {PREFIX}__RETRYING__WAIT__RANDOM__(MIN|MAX) min=0,max=3600 随机等待 minmax 秒之间进行重试
wait=exponential(multiplier=f32, min=f32, max=f32, exp_base=u32) {PREFIX}__RETRYING__WAIT__EXPONENTIAL__(MULTIPLIER|MIN|MAX|EXP_BASE) multiplier=1, min=0, max=3600, exp_base=2 等待倍数 * _exp_base_^(重试次数 - 1) + 最小秒数之间的时间,从最小秒数开始,然后到最大秒数,之后都是最大秒数。

只能使用一个等待选项。

  • 重试

本节描述了指定重试条件的配置选项。

配置选项 操作系统环境 默认 描述
retry=if_errors(error_1, error_2, error_2) 不适用 - 仅在特定错误上重试
retry=if_not_errors(error_1, error_2, error_3) 不适用 - 在特定错误上不重试

只能使用一个重试选项。

使用OS环境变量更新重试配置

在某些情况下,重试配置需要更新运行时配置值。例如,当需要每个环境(dev、prod、stage)、系统、单元测试等不同次数的尝试时很有用。

重试允许使用特殊配置选项envs_prefix(如)覆盖运行时的宏配置,例如

#[retrying::retry(<retry configurations>,envs_prefix="test")]

⚠️ 限制

  • 只能覆盖配置值,不能覆盖配置选项。这意味着,例如,如果配置选项stop=attempts(1))在宏代码中没有定义,那么操作系统环境变量{PREFIX}__RETRYING__STOP__ATTEMPTS不会影响代码执行。换句话说,操作系统环境变量只能覆盖配置选项的值,而不能改变选项本身。
  • 操作系统环境变量中的配置选项优先于源代码中的选项。
  • 如果未设置操作系统环境变量,则宏使用其配置(源代码)中的值。
  • 如果操作系统环境变量的格式不正确(例如,对于数值配置指定了非数值值),则重试宏会忽略此类配置,记录错误到stderr并继续使用代码中的值。

使用示例

#[retrying::retry(stop=attempts(2),envs_prefix="test")]

使用上述配置,宏在运行时会检查操作系统环境变量TEST__RETRYING__STOP__ATTEMPTS(不区分大小写)的存在,如果变量已设置,则重试尝试的次数将是TEST__RETRYING__STOP__ATTEMPTS的值。如果操作系统环境变量列表中包含具有相同前缀的多个配置选项,则宏会忽略操作系统环境变量,并从代码中获取配置值。

功能

tokio - 为使用tokio异步运行时构建重试库。 async_std - 为使用async_std异步运行时构建重试库。

示例

示例位于./crates/retrying/example,可以使用cargo进行测试。同步

cargo run --example sync

异步tokio

cargo run --features="tokio" --example tokio

异步async-std

cargo run --features="async_std" --example async_std

理解宏

retrying::retry宏并不是魔法,它只是帮助开发者避免编写额外代码。生成的代码取决于提供的配置,并且可能会在未来的版本中更改。代码生成示例

#[retry(stop=(attempts(4)|duration(2)),wait=fixed(0.9))]
fn my_method(in_param: &str) -> Result<i32, ParseIntError> {
    in_param.parse::<i32>()
}

生成的代码

fn my_method(in_param: &str) -> Result<i32, ParseIntError> {
    let mut retrying_context = ::retrying::RetryingContext::new();
    use ::retrying::stop::Stop;
    let retrying_stop =
        ::retrying::stop::StopAttemptsOrDuration::new(4u32, 2f32);
    use ::retrying::wait::Wait;
    let retrying_wait = ::retrying::wait::WaitFixed::new(0.9f32);
    loop {
        match { in_param.parse::<i32>() } {
            Ok(result) => return Ok(result),
            Err(err) if !retrying_stop.stop_execution(&retrying_context) => {
                match err {
                    std::num::ParseIntError { .. } => (),
                    _ => break Err(err),
                };
                retrying_context.add_attempt();
                ::retrying::sleep_sync(retrying_wait.wait_duration(&retrying_context));
            }
            Err(err) => break Err(err),
        }
    }
}

可以使用cargo检查生成的代码。例如,以下命令显示了所有示例的生成代码,

cd ./crates/retrying
cargo rustc --profile=check --examples -- -Zunpretty=expanded

依赖关系

~0.5–14MB
~144K SLoC