Skip to content

fix(net): blob route cap, root_path/trailing-slash cap matching, throttled baseline-skip log - #52

Merged
wikithoughts merged 1 commit into
mainfrom
overnight/coordinator-cap-followups
Oct 11, 2026
Merged

wikithoughts merged 1 commit into
mainfrom
overnight/coordinator-cap-followups

Conversation

@wikithoughts

Copy link
Copy Markdown
Owner

Follow-ups from the PR #50 review (claude-review-pw-50.md, verdict MERGE-WITH-FOLLOWUP). This change touches only the cap table, _body_cap_for, the baseline-skip log, the README cap lines and tests/test_coordinator_limits.py.

What changed

  • Blob upload route cap (Medium 1).
    • POST /jobs/{id}/blobs/{hash} now has its own cap: _BLOB_BODY_CAP = _BLOB_CAP + 16 KiB, which is 528 KiB. It was the 4 MiB ceiling.
    • The cap is derived from the handler's constant. _BLOB_CAP moved up next to the other caps and is defined only once.
    • The upload body is the raw chunk (application/octet-stream, operator.py:197-202), with no JSON or multipart wrapper. So the extra 16 KiB is only slack: at the boundary, put_blob's own exact 512 KiB check still decides, and it still answers chunk too large.
  • Cap matching uses the app-relative path (Medium-Low 3).
    • _body_cap_for(method, path, root_path) removes a whole-segment root_path prefix before matching, the same way Starlette's get_route_path does. uvicorn 0.54 builds scope["path"] as root_path + path.
    • It also strips trailing slashes. So /pw/users and /users/ now get the 64 KiB cap for /users instead of falling back to the ceiling.
    • The middleware passes scope["root_path"] through.
  • Baseline-skip log throttle (Low 5).
    • The [baseline] skipped … line is printed for the 1st skip and then every 100th (_BASELINE_SKIP_LOG_EVERY).
    • The /metrics baseline_skipped_busy counter still counts every skip exactly.
  • README: blob uploads are no longer described as "at the ceiling". It also notes that a trailing slash or --root-path gets the same cap as the plain route.
  • Tests (Medium 2):
    • Exact cap passes and cap+1 gets 413 on /users, on /tasks/{id}/result (4 MiB, spy shows the endpoint ran), on /jobs (4 MiB) and on blobs (512 KiB handler edge plus 528 KiB pre-auth route edge).
    • GET with a body over 64 KiB gets 413.
    • Trailing-slash and root_path-prefixed paths get the route cap.
    • The log is throttled and the counter stays exact.

Fails on main where behaviour changed

I ran the new test file against origin/main's coordinator_app.py: 6 failed, 26 passed. The failing tests:

  • test_blob_route_cap_is_the_chunk_cap_plus_slack_not_the_ceiling. On main it errors on the missing _BLOB_BODY_CAP; without the new route cap, a 528 KiB+1 blob would reach auth and get 401.
  • test_trailing_slash_gets_the_route_cap_not_the_ceiling. On main the request gets a 307 instead of a 413.
  • test_root_path_prefix_gets_the_route_cap
  • test_skip_log_is_throttled_but_the_counter_stays_exact
  • test_busy_slots_skip_the_baseline_with_a_log_line_and_a_counter
  • test_body_cap_for_routes_and_the_ceiling

The exact-cap tests for /users, /result and /jobs and the GET test pass on main too. That is expected: they cover behaviour that was already right but untested.

Verification (rebased on 003a0a4, head acc1f27)

  • ruff check . && pytest tests/ -q --cov=passiveworkers --cov-fail-under=75 → exit 0: All checks passed!, 807 passed, 1 skipped, total coverage 83.64%.
  • python -m py_compile $(git ls-files '*.py') → exit 0.
  • pyright (now blocking for passiveworkers/net since ci: make pyright blocking, pin actions to commit SHAs, add CodeQL #51; installed into the local venv) → exit 0, 0 errors, 0 warnings, 0 informations.
  • There is no UI change, so I did no browser check.

Not verified

  • I did not run a real uvicorn --root-path server. The root_path test copies uvicorn 0.54's root_path + path scope using Starlette's TestClient (root_path="/pw").
  • CI was not watched (the lane rules forbid it).
  • The /jobs and /result ceilings are unchanged. The review's suggestion of about 256 KiB for /jobs was not part of this brief.

🤖 Generated with Claude Code

…ttled baseline-skip log

Follow-ups from the PR #50 review:
- Blob uploads get their own route cap, _BLOB_BODY_CAP = _BLOB_CAP + 16 KiB slack, derived from
  the handler's chunk constant (now defined with the other caps), instead of the 4 MiB ceiling.
- _body_cap_for matches the app-relative path: a whole-segment root_path prefix (uvicorn
  --root-path puts it in scope["path"]) and trailing slashes are stripped first, as Starlette's
  router does, so /pw/users and /users/ get /users's 64 KiB cap instead of the ceiling.
- The "baseline skipped" log line is printed for the first skip and every 100th; the
  /metrics counter stays exact.
- README cap wording fixed (blob uploads are no longer "at the ceiling").
- Tests: exact-cap passes and cap+1 is 413 for /users, /result, /jobs and blobs; GET with a
  >64 KiB body is 413; trailing-slash and root_path-prefixed paths get the route cap; the
  log throttle keeps an exact count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wikithoughts
wikithoughts merged commit a48f06a into main Oct 11, 2026
13 checks passed
@wikithoughts
wikithoughts deleted the overnight/coordinator-cap-followups branch October 11, 2026 09:31
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.

1 participant