Download internal/server/backoff.go from a3216/gcli2api: direct link, hf CLI and curl.
- Browser
- Download file 2.78 kB
-
https://huggingface.co/spaces/a3216/gcli2api/resolve/main/internal/server/backoff.go
- Command line
-
hf download hf://spaces/a3216/gcli2api/internal/server/backoff.go
-
curl -L -o backoff.go https://huggingface.co/spaces/a3216/gcli2api/resolve/main/internal/server/backoff.go
2.78 kB
| // backoff.go 轮转退避与抖动的单一事实来源(WAF 403 修复 P0-2/P0-1 共用): | |
| // 指数基数/封顶/抖动比例一处定义,chatCompletions 轮转退避与 WAF 软冷却基数 | |
| // (handler.wafCooldownBase)共用同一 jitterDur,不在 handler 与 upstream 各写一份。 | |
| package server | |
| import ( | |
| "context" | |
| "math/rand/v2" | |
| "time" | |
| ) | |
| // rotateBackoffBase 轮转退避基数(对齐官方 intl CLI computeRequestRetryDelayMs | |
| // 的 500ms 形态,WAF 403 并发研究报告 §2.1/§6 P0-2)。测试可置 0 跳过等待 | |
| // (TestMain 已置 0 加速轮转测试;退避界断言测试临时恢复)。 | |
| var rotateBackoffBase = 500 * time.Millisecond | |
| const ( | |
| // rotateBackoffCap 轮转退避封顶(报告 P0-2 建议 8s:轮转上限默认 3 次, | |
| // 实际等待序列 500ms/1s,封顶只约束极端配置下的 MaxRotate)。 | |
| rotateBackoffCap = 8 * time.Second | |
| // jitterFraction 抖动比例(±25%,对齐 intl CLI delay×(1±0.25) 形态)。 | |
| jitterFraction = 0.25 | |
| ) | |
| // jitterDur 给时长施加 ±jitterFraction 的均匀抖动,返回 [d·(1-f), d·(1+f)] 区间值。 | |
| // d<=0 原样返回(零等待不抖动)。抖动目的是打散多请求同相位重试(WAF 频控按 | |
| // 密度判罚,齐步走的退避会以固定周期再次聚团)。 | |
| func jitterDur(d time.Duration) time.Duration { | |
| if d <= 0 { | |
| return d | |
| } | |
| f := 1 + (rand.Float64()*2-1)*jitterFraction | |
| out := time.Duration(float64(d) * f) | |
| if out < 0 { | |
| return 0 | |
| } | |
| return out | |
| } | |
| // backoffAfter 返回第 n 次轮转(0 基:首次失败换号前 n=0)前应等待的退避时长: | |
| // base·2^n 封顶 rotateBackoffCap,再施加 ±25% 抖动。base 置 0(测试)时恒 0。 | |
| // 用逐次翻倍而非位移:base 调整后无需同步维护移位上限,溢出由封顶比较兜底。 | |
| func backoffAfter(n int) time.Duration { | |
| d := rotateBackoffBase | |
| if d <= 0 { | |
| return 0 | |
| } | |
| for k := 0; k < n && d < rotateBackoffCap; k++ { | |
| d *= 2 | |
| if d <= 0 { // 翻倍溢出成非正数:直接按封顶处理 | |
| return jitterDur(rotateBackoffCap) | |
| } | |
| } | |
| if d > rotateBackoffCap { | |
| d = rotateBackoffCap | |
| } | |
| return jitterDur(d) | |
| } | |
| // sleepCtx 可取消的等待:ctx 取消立即返回 false(客户端断连/优雅停机不必等退避 | |
| // 睡醒),等满返回 true。d<=0 立即放行。与 scheduler.sleepCtx 同模式(该函数未 | |
| // 导出且 scheduler 不宜被 server 反向依赖,按任务书「等价物」口径在消费侧实现)。 | |
| func sleepCtx(ctx context.Context, d time.Duration) bool { | |
| if d <= 0 { | |
| return ctx.Err() == nil | |
| } | |
| t := time.NewTimer(d) | |
| defer t.Stop() | |
| select { | |
| case <-ctx.Done(): | |
| return false | |
| case <-t.C: | |
| return true | |
| } | |
| } | |