言韧:重试与断路器
言韧 1.0 的确定性退避、可观察执行、停止控制与三态断路器。
言韧(yanxu-retry)1.0.0 把重试策略、执行控制和断路状态分开。生产环境可以真实等待,测试或外部调度器可以注入等待器、观察器、停止判定与单调时间源,同时复用相同的尝试次数、退避和断路逻辑。
版本与安装
| 项目 | 稳定值 |
|---|---|
| 包名 | 言韧 |
| 版本 / 公开标签 | 1.0.0 / v1.0.0 |
| 最低言序 | 1.1.6 |
| 依赖 | 无 |
| 构建目标 | 字节码 |
yanbao add 言韧 \
--git https://github.com/yanxulang/yanxu-retry.git \
--rev v1.0.0 \
--version '^1.0'[依赖]
言韧 = { git = "https://github.com/yanxulang/yanxu-retry.git", 修订 = "v1.0.0", 版 = "^1.0" }应把生成的 言序.lock与应用一同提交。
核心能力与快速开始
引「包:言韧」为 言韧;
法 请求一次(次数:数):文 则
若 (次数 小于 3) 则
抛 「YANQIU_TIMEOUT:请求超时」;
终
归 「响应成功」;
终
定 策略 为 言韧.重试策略(4,0.1,2,1)
.设抖动(0.5,2026);
定 可恢复:法 为 言韧.可重试代码(【「YANQIU_TIMEOUT」】);
言 言韧.执行(策略,请求一次,可恢复);最大次数包含首次调用;操作收到从 1 开始的尝试编号。判定器只在操作失败且还有下一次机会时执行。
策略与退避
重试策略(最大次数, 初始延迟秒, 倍率, 最大延迟秒)描述完整计划。无抖动时,第 n次失败后的延迟为:
min(初始延迟秒 × 倍率^(n - 1), 最大延迟秒)| 入口 | 用途 |
|---|---|
默认策略() | 通用指数退避默认值 |
立即策略(次数) | 延迟为零的计划 |
基础延迟秒 / 延迟秒 | 查看无抖动 / 实际延迟 |
延迟表 / 计划表 | 查看完整等待及累计计划 |
执行 | 使用真实等待,成功返回值、最终失败传播业务误 |
立即执行 | 复用计划但跳过真实等待 |
尝试执行 | 返回固定结构化结果而不抛最终业务错误 |
设抖动(比例, 种子)采用确定性向下抖动。同一策略、种子和失败次数在树解释器与字节码 VM 中得到相同结果;种子不是秘密,也不是密码学随机数。不同客户端应使用不同种子,测试则应固定种子。
生产代码应优先用 可重试代码白名单识别暂时性错误。总是重试和从不重试只适合受控边界,不应把错误消息文字当稳定分类协议。
可观察与可停止执行
法 外部等待(秒:数,上下文:典):空 则
# 交给调度器;测试也可以只记录延迟
归 空;
终
法 观察(事件:典):空 则
言 事件【「阶段」】;
归 空;
终
定 控制 为 言韧.执行控制()
.设等待器(外部等待)
.设观察器(观察);
定 结果 为 言韧.受控执行(策略,请求一次,可恢复,控制);还可用 设停止判定在每次尝试前协作式停止。生命周期事件模式 v1 的阶段为开始、失败、等待、成功、放弃、耗尽和停止,字段包括次数、最大次数、累计等待、当前等待与错误。
判定、等待、观察和停止回调失败分别使用 YANREN_PREDICATE、YANREN_WAITER、YANREN_OBSERVER和YANREN_STOP_CALLBACK,不会被误当成业务失败再次重试。成功事件的观察器即使失败,已经成功的业务操作也不会重做。
三态断路器
定 断路 为 言韧.断路器(5,30000);
法 调用上游():文 则
归 「上游结果」;
终
言 断路.调用(调用上游);连续失败达到阈值后从关闭进入开启;冷却到期后进入半开,并且只允许一个在途探针。探针成功关闭断路,失败重新开启并重置冷却。
是否允许()只查看状态,不占用半开许可。手工编排必须调用 获取许可(),并保证随后调用 记成功()或记失败();通常应优先使用自动完成记录的 调用()。拒绝调用使用 YANREN_OPEN。
重试与断路器可以直接组合:
定 值 为 言韧.受控执行经断路器(
策略,断路,请求一次,可恢复,控制
);每次业务尝试都通过同一个断路器许可。若允许重试 YANREN_OPEN,等待计划必须覆盖断路冷却,并由上层总截止时间约束。
资源、权限与安全边界
| 项目 | 硬上限 |
|---|---|
| 尝试次数 | 4096 |
| 单次延迟 | 86400 秒 |
| 计划累计等待 | 604800 秒(7 天) |
| 退避倍率 | 1000 |
| 错误代码白名单 | 64 |
| 断路失败阈值 | 4096 |
| 恢复时间 | 604800000 毫秒(7 天) |
言韧无第三方依赖,不申请文件、网络、监听、环境、进程或原生扩展权限。应用传入的操作与回调仍在顶层应用的权限范围内运行,不能把不可信脚本直接用作回调。
安全使用与已知限制
- 只重试明确暂时且可安全重放的操作;写操作必须使用幂等键、唯一约束、事务或业务去重。
- 避免在客户端、代理和服务多层叠加重试,否则请求与写入会乘法放大。
- 停止判定是协作式的,不会抢占正在执行或阻塞中的业务操作。
- 断路器是同步、进程内状态机,不提供跨线程、跨进程或分布式原子协调,也不替代认证、限流或配额。
- 自定义时间源必须返回非负、安全、单调不减的毫秒;等待器与断路器应使用同一时间域。
错误详情包含位置与踪迹,写入遥测或返回客户端前必须按数据策略过滤。