fix(peer): stop the request body upload on an early stream/cancel - #129
Conversation
A stream/cancel that arrived while the request message was still being sent found no transmitter yet and was dropped, so the client then uploaded the whole request body and the server discarded it. ClientPeer now remembers the cancel and cancels the body instead of transmitting it. Co-Authored-By: Claude <noreply@anthropic.com>
@standard-server/aws-lambda
@standard-server/core
@standard-server/fastify
@standard-server/fetch
@standard-server/node
@standard-server/peer
@standard-server/shared
commit: |
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- An early
stream/cancelis now remembered —ClientPeerrecordsstate.streamCancelledinmessage()and, after the request-messagesendresolves,transmitRequest()returns before clearinguntransmittedBodyor constructing a transmitter, so thefinallyreleases the body viacancelStandardBodyand no chunks go out. - Both streamed body kinds covered — the unit tests exercise octet-stream and event-stream request bodies, injecting
stream/cancelfrom inside the requestsend. connect()gainswaitForRemote— each wire send can await the remotemessage(), so replies arrive while the send is in flight; the pre-existing late-send test now reuses the helper instead of its own copy.- Integration coverage — a
ServerPeer/codec round-trip where the handler cancels the request body mid-send.
Verified locally: all 255 peer tests pass, type:check is clean, and reverting the two client.ts hunks makes all three new tests fail. The assertions are exact (send.mock.calls.map(...).toEqual(['request'])), so they genuinely pin the behavior rather than absorbing whatever is sent.
DeepSeek Flash (default — pick a model for stronger reviews) | 𝕏

When the server cancelled a streamed request body while the client was still sending the request message,
ClientPeerignored thestream/canceland then uploaded the whole body anyway. The server threw every chunk away. For a long or endless body, the upload kept running until the request ended. The client now remembers an earlystream/canceland cancels the body instead of sending it.This only happens on transports whose
sendresolves late, for example one that waits for the other side to acknowledge the message, and only when the request stays open after the cancel (for example, with a streamed response).Fixes
stream/cancelis no longer lost: no body chunks are sent and the local body is cancelled.Testing
stream/cancelwhile the request is being sent. They check that the body is cancelled and only therequestmessage goes out.ServerPeerand message encoding.connect()test helper gained awaitForRemoteoption. The existing "waits for full remote processing" test now uses it instead of its own copy of the connection code.🤖 Generated with Claude Code