Bound patch API connects and stalled reads (#570) - #581
Conversation
Assisted-by: Claude Code:claude-opus-5-5
scan, get, apply and vex talk to the patch API through two reqwest clients that had no connect or read timeout, so a stalled proxy, load balancer or half-open connection hung the run until the CI job was killed. Both clients now take one named ApiTimeouts policy (10 s connect, 60 s of silence on an open connection). A stall fails as ApiError::Network, which the proxy fallback already handles; a download that keeps streaming is never cut off. Fixes #570 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
|
bugbot run Generated by Claude Code |
|
[burn-down agent] Labeled Ready for review at
Generated by Claude Code |
|
Reviewed final head The reproduced P2 JSON body-stall issue is fixed: all three JSON readers retain timeout/transport failures as The subsequent scan-performance failure was a stale Berry fixture, not a measured slowdown. Both main and this PR correctly rewrite Ready to merge as-is from this review. Final-head CI is complete: 332 successful checks, 6 skipped; no failures or pending checks. Bugbot passed, there are no unresolved review threads, and the PR is mergeable. No full local workspace or timing run was repeated. |
|
BugBot review Please review the JSON body timeout fix at |
|
[agent] The
Generated by Claude Code |
…tch-581-benchmark-20261002
(cherry picked from commit 329b146)
|
BugBot review Please review final commit |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 202e477. Configure here.
Fixes #570.
Both authenticated and header-free
ApiClientclients now use a shared transport policy: a 10-second connect bound and a 60-second idle read bound. Stalled proxies, half-open connections, and incomplete response bodies fail instead of hanging indefinitely.Behavior and implementation
ApiTimeoutsinapi/retry.rssupplies the named defaults and applies them to both client builders.with_api_timeoutsprovides a test override.ApiError::Network, preserving their underlying cause. Completed malformed JSON remainsApiError::Parse.Validation
43269f46; the final202e4774keeps the API source and timeout tests byte-identical and changes no runtime dependency versions.203e092b. Its benchmark fixture now requires bothpackage.jsonandyarn.lockfor hosted Berry pinning, matching the descriptor-resolution change already on main.329b1467in Stream ZIP member hashes during vendored verification #587. No ZIP verification changes are included. All 29 benchmark harness tests pass; the identical harness already passed against the same main baseline.Risk and scope
An API response that remains silent for more than 60 seconds now fails; long computations before the first response byte must fit that idle bound. Blob/diff retry policy, merging the retry systems, and streaming blob/diff implementation (#571) remain outside this change.
Note
Medium Risk
Silent API responses longer than 60s now fail; environments with very slow first-byte latency may see new network errors where commands previously hung.
Overview
Patch API traffic (
scan,get, blob/diff downloads, vendoring) no longer blocks indefinitely when a proxy or connection stalls. Both authenticated and public-proxy HTTP clients shareApiTimeouts: 10 s to connect and 60 s of silence on an open socket before failing withApiError::Network.The read bound is per idle period, not a total transfer limit—streams that keep sending data still complete. Stalled or truncated JSON bodies are classified as network errors (not parse errors), including vendor package-reference responses where retry hints are unchanged. Tests can shorten bounds via
with_api_timeouts.The Yarn Berry benchmark fixture now expects hosted redirects to rewrite
package.jsonas well asyarn.lock, matching descriptor-resolution pinning on main.Reviewed by Cursor Bugbot for commit 202e477. Configure here.