Repository navigation
Fix proxy batch fallback ignoring API concurrency (#614) - #1817
Conversation
Assisted-by: Claude Code:claude-opus-5-5
When the public proxy rejects a batch search chunk, the client falls back to one GET per package. That fallback kept up to 10 requests in flight from its own private constant, so it ignored the proxy cap of 4 and SOCKET_API_CONCURRENCY (even =1 still sent 10 at once), and a tight open-file limit did not make it serial either. The batch path now reads its cap from utils::concurrent::api_concurrency when the client is built, like every other patch-API window, and the private constant is gone. Tests pin the shared peak at the proxy cap and at 1 under SOCKET_API_CONCURRENCY=1. Fixes #614 Assisted-by: Claude Code:claude-opus-5-5
The per-package fallback ran its GETs in groups, and waited for the slowest one in a group before starting the next, so one slow or throttled GET left the other slots idle. Every GET now waits on the shared slot pool directly, which keeps the proxy's cap busy. Only a proxy client reads SOCKET_API_CONCURRENCY for these slots, so an org client no longer prints a debug line about a bad value. The tests set the variable only while the client is built and run a smaller serial case, so they no longer leave it set for other tests. Refs #614 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
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 3317a95. Configure here.
|
Burn-down agent: labeled Ready for review at
Generated by Claude Code |
Final review briefWhat it does. Fixes #614. When the public proxy rejects a batch chunk or lacks Risk: low-medium. One file. Intended behavior change: the default fallback (and the batch POSTs that share the pool) drops from 10 to 4 in flight on the proxy, which can slow scans that hit the fallback. Look here
Verified. Read the full diff and the POST path. Ran Changes I made. None. Open questions. None blocking. Spawned fallback tasks don't inherit the Auto-merge is armed, so approving sends it straight to the merge queue. Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #614
Summary
When the public proxy rejects a batch-search chunk (a validation 400, which one exotic PURL is enough to cause) or predates
POST /patch/batch, the client falls back to one GET per package. That fallback kept up to 10 requests in flight because of a private constant. So it ignored the proxy cap of 4 andSOCKET_API_CONCURRENCY(=1still sent 10 at once), and it stayed concurrent under a tightRLIMIT_NOFILE.Root cause
api/client.rsset the size of the proxy batch path's slot pool and fallback groups fromPROXY_BATCH_PATH_CONCURRENCY = 10. Every other patch-API window gets its limit fromutils::concurrent::api_concurrency.Changes
proxy_batch_slotsfromapi_concurrency(true)when it is built: 4 by default, lower underSOCKET_API_CONCURRENCY, and 1 under a tight fd limit. An org client never uses these slots and doesn't read the env for them, so it adds no duplicate--debug"ignoring SOCKET_API_CONCURRENCY" line.PROXY_BATCH_PATH_CONCURRENCYis deleted. No patch-API pacing constant is left outsideutils::concurrent.search_patches_batchno longer says "concurrency 10".Behavior change (intended, per the issue's acceptance criteria): the default fallback fan-out on the public proxy drops from 10 to 4. On the proxy the override can only lower the cap, by design (
utils/concurrent.rs).The issue's second point (
registry_concurrency()had no caller) is already resolved onmain: it is now called frompatch/redirect/upstream/client.rsandupstream/npm.rs.Tests (red → green)
api_concurrency(true)(4), not 10proxy_batch_path_cap_tests::concurrent_batches_share_the_legacy_fallback_capSOCKET_API_CONCURRENCY=1gives a peak of 1proxy_batch_path_cap_tests::the_legacy_fallback_honors_the_concurrency_overrideThe tests set
SOCKET_API_CONCURRENCYonly while the client is built (it is read there) and restore it right away, so the variable is never left set while other tests run.Local checks
cargo fmt --all -- --check: cleancargo clippy --workspace --all-features -- -D warnings: cleancargo test -p socket-patch-core --all-features --lib: 6924 passed, 4 failed. The 4 failures (copy_tree::relax_loop_must_not_traverse_symlinked_root,vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry,pypi_poetry::wire_write_failure_…,pypi_requirements::wire_failure_rolls_back_…) depend on read-only directories blocking writes. They fail only because this sandbox runs as root (uid 0), are unrelated to this diff, and CI runs as non-root.cargo test -p socket-patch-cli --all-features --lib --bins: 936 passedcargo test -p socket-patch-cli --all-features --test scan --test cli --test scan_api_retry_e2e: 247 + 113 + 5 passedcargo test --workspaceran out of disk in the sandbox while linking every e2e binary, so CI is the full-suite gate. No wrapper (npm/,pypi/,gem/) is affected: this is client-internal pacing.Code review (
/code-review high)Fixed: chunk stalls (groups → shared slot pool), the stale "concurrency 10" doc, a slow 12 s serial test (now 6 GETs), the env var left set during the test, the env read and debug line on org clients, and a duplicate test
EnvGuard.Not fixed:
hold_back_debugtask-local": this predates the PR (the old code spawned the same way). It is out of scope and worth a separate issue.https://claude.ai/code/session_011f9aeT8JHNQ414VVv6qyZm
Generated by Claude Code