Skip to content

fix(baidu_netdisk): probe once when the rate-limit pause ends - #3255

Open
zeroornull wants to merge 2 commits into
OpenListTeam:mainfrom
zeroornull:fix/baidu-ratelimit-cooldown-clean
Open

zeroornull wants to merge 2 commits into
OpenListTeam:mainfrom
zeroornull:fix/baidu-ratelimit-cooldown-clean

Conversation

@zeroornull

Copy link
Copy Markdown
Contributor

Fixes #3254

Separate from #3208 (List visibility). Do not merge the branches.

Summary / 摘要

When Baidu returns errno 31034 (frequency control), the driver pauses. Previously, when that pause expired every waiting request fired at once; if Baidu was still throttling they all got 31034 again and the pause escalated. This PR turns the cooldown into a half-open circuit breaker so only one probe goes out at expiry.

百度返回 errno 31034(频控)时驱动会暂停。原先暂停结束后,所有等待中的请求会一起发出;若百度仍在限流,它们会再次全部收到 31034,暂停时间被反复拉长。本 PR 把 cooldown 改成半开熔断:到期时只放行一个 probe。

Behavior / 行为:

  • First 31034 opens the breaker (base 8s, doubles to 30s, with jitter). 31034 from requests already in flight before it opened is ignored.
    首次 31034 打开熔断(基准 8s,翻倍到 30s,带抖动);熔断打开前已发出的请求再收到 31034 会被忽略。
  • When the pause ends, exactly one request goes out as a probe; the others keep waiting.
    暂停结束时只放行一个 probe,其余继续等待。
  • Probe gets 31034: pause again (escalated) and probe at the next expiry.
    probe 仍是 31034:再次暂停(加长)并在下次到期再 probe。
  • Probe gets any other Baidu answer: close the breaker and release everyone.
    probe 得到其它百度响应:关闭熔断,放行所有等待者。
  • Probe fails without a verdict (network error, ctx cancelled): hand the probe slot to the next waiter.
    probe 没有结论(网络错误、ctx 取消):把 probe 名额交给下一个等待者。
  • Waiting honours ctx and a per-call 35s budget; after that the call fails with the rate-limit error (S3 maps to 503 SlowDown).
    等待尊重 ctx 与单次调用 35s 预算;超时后以限流错误失败(S3 映射为 503 SlowDown)。

Files / 文件:

  • drivers/baidu_netdisk/ratelimit.go
  • drivers/baidu_netdisk/ratelimit_test.go
  • drivers/baidu_netdisk/util.go

This is separate from #3208 (pending List visibility). Do not merge the branches.

与 #3208(写后 List 可见性)无关,不要合并分支。

Testing / 测试

  • Unit tests in drivers/baidu_netdisk/ratelimit_test.go (breaker open / probe success / probe still 31034 / probe handoff / wait budget).
  • Live S3 delete probe against production BaiduNetdisk (2026-10-21): 200/200 DeleteObject returned 204; 32 attempts saw 503 SlowDown and recovered (openlist-ratelimit-live-result-20261021112251.json).
  • Production observation (image deploy/ratelimit-plus-debug / 3d383e45, through 2026-10-24 daily backups):
    • sg-qiniu kine-percona-backup on 2026-10-24 03:00 CST: completed successfully; complete.json HeadObject verified through OpenList→Baidu (this was the prior 404 failure mode).
    • Velero daily-full-clean-20261023190013 (started 2026-10-23 19:00 UTC = 2026-10-24 03:00 CST): PartiallyFailed with 1 error; failure is alertmanager PVB readiness timeout (context deadline exceeded), not Baidu rate-limit. 109/110 PodVolumeBackups Completed.
    • OpenList logs: 31034 still appears during heavy Velero windows (e.g. 494 in the 10-23 rotated log) and the breaker rides them out (no SlowDown / RateLimited strings left in access logs for the quiet current window; current log.log has 0×31034). errno 600 on list retried and succeeded.
  • This PR head is the clean fix-only rebase (fix/baidu-ratelimit-cooldown-clean, tip 129ab900) with no debug logging and without fix(op): keep written objects visible until a List returns them #3208 commits.

AI Disclosure / AI 使用声明

  • This PR includes AI-assisted content. / 此 PR 包含 AI 辅助内容。
  • Other: Grok Bot
  • Scope: Code generation, Tests, Documentation, Translation
  • I have reviewed and validated all AI-assisted content included in this PR.

… deletes

Baidu answers bursts of filemanager calls with errno 12 whose info[] item
carries 31034 (frequency control). The driver only looked at the outer errno,
retried 3 times within ~5s while the window lasts ~16s, and the S3 gateway
discarded fs.Remove's error, so DeleteObject always returned 204 and kopia
never retried: objects were silently left behind.

baidu_netdisk:
- parse info[].errno of failed batches; 31034 (outer or per item) is a rate
  limit and unwraps to errs.TemporaryCapacity
- shared per-instance cooldown: on 31034 all requests pause (8s, doubling on
  consecutive windows, capped at 30s, small jitter, reset after a success);
  hits inside an open window do not extend it; no limiter otherwise
- per-call cooldown wait budget (35s), then the rate-limit error is returned
- requests honour ctx; manage() takes ctx
- delete of a missing path (-9 / 31066) is success and not retried

s3:
- DeleteObject returns Remove errors; rate limits map to 503 SlowDown so
  clients back off and retry, other errors to 500; missing keys stay 204
- DeleteMulti reports SlowDown per key instead of always InternalError
When the cooldown expired every waiting request fired at once; if Baidu was
still throttling they all got 31034 again and the pause escalated. Turn the
cooldown into a half-open circuit breaker:

- the first 31034 opens it (8s, doubling to 30s, jitter); 31034 from requests
  sent before it opened is ignored
- when the pause ends exactly one request goes out as a probe, the others
  keep waiting
- probe gets 31034: pause again (escalated) and probe at the next expiry
- probe gets any other Baidu answer: close the breaker, release everyone
- probe fails without an answer (network error, ctx cancelled): hand the
  probe slot to the next waiter
- waiting honours ctx and the per-call 35s budget, after which the call
  fails with the rate-limit error (S3 503 SlowDown)
@cursor
cursor Bot force-pushed the fix/baidu-ratelimit-cooldown-clean branch from 18d17e3 to 503dde9 Compare October 24, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] 百度网盘 31034 频控暂停结束后请求风暴导致熔断反复升级 / BaiduNetdisk 31034 pause stampede

1 participant