The branch passes every check, including make verify-device on straylight and repeated timing runs under load. Reading and probing found that inferproxy does not pass an upstream close on to a client that is still sending, and that the chunked body reader delivers a stream only when the caller's buffer fills or the stream ends. Both were also gaps in the tasks and tests, so tasks 14 and 15 carry the fixes with new tests checked against the reference. The Model column is corrected: tasks 04 to 06 and 08 to 13 were Ornith. Lessons gain four implementer tips and five task-writing tips; three rules are promoted to AGENTS.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2.6 KiB
M2a task 14: pass the upstream's close on to the client (review follow-up)
Branch: m2a (run git switch m2a; git status --short must be empty, otherwise stop)
Commit subject: Close the client side when the upstream closes, in inferproxy
Goal
The M2a review found that inferproxy only closes towards the client after the client has stopped
sending. loopd's HTTP client never stops sending on its own: it keeps its side open until it
drops the connection. So when llama-server closes, or dies in the middle of an answer, the client
is not told; it sits until its own liveness timeout and reports Stalled instead of
StreamClosedEarly, thirty seconds late. A body that runs to the close would hang the same way.
Task 02, rule 3, said: "When the server stops sending, the exchange is over: close both." The
current code waits for both copy threads to finish instead. This was partly the plan's fault: every
test client in forward.rs half-closed after sending, so the gap could not show. The new test
sends without half-closing.
Files
- Copy (replacing the old one):
crates/inferproxy/tests/forward.rs - Modify:
crates/inferproxy/src/lib.rs,docs/implementer-log.md
Required behaviour
- When the server-to-client copy ends, for any reason, shut down the client connection (both directions) and the server connection, so that the client's read returns 0 at once and the client-to-server copy thread ends. Do this after releasing the open-connection place, as rule 4 of task 02 requires.
- Everything else from task 02 still holds, including the half-close when the client stops sending first.
Steps
- 1. Copy.
git switch m2a, thencp docs/plans/M2a/files/crates/inferproxy/tests/forward.rs crates/inferproxy/tests/ - 2. See it fail.
cargo test -p inferproxy --test forward. Expected: 1 of 7 fails,the_upstreams_close_reaches_a_client_that_is_still_sending, with a timeout. - 3. Fix
lib.rs. Runcargo fmt --all. - 4. See it pass.
cargo test -p inferproxy --test forward, ten times in a row. Expected:7 passedevery time. - 5. Run the gate.
make gate. Expected last line:gate: ok. - 6. Log and commit.
git add crates/inferproxy docs/implementer-log.md && git commit
Done when
cargo test -p inferproxy --test forwardreports 7 passed, ten runs in a row;make gateprintsgate: ok;cmp crates/inferproxy/tests/forward.rs docs/plans/M2a/files/crates/inferproxy/tests/forward.rsprints nothing.
Stop and report if
- Passing the new test breaks
forwards_both_ways_and_passes_the_half_close_on.