You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
drpcwire,drpcstream: return the real error from a preempted send
A send blocked on backpressure used to return an opaque "interrupted"
sentinel from WriteFrame, which the data path then remapped through
CheckCancelError. WriteFrame lives in drpcwire and cannot know why a send was
stopped, so it could only return a generic error and leave the stream to
recover the cause.
Pass the stream's send signal to WriteFrame directly and have it return that
signal's error when the signal fires. The send signal is the write side's own
"stop sending" signal, and terminate() always sets it, so a parked send is
woken on every termination and returns send.Err(), which is io.EOF in the
cancel and error cases. That is the same error the write loop's guard already
returns when send is set before a frame is sent, so the parked and unparked
paths now return the same thing.
This is why the CheckCancelError remap on the write path is removed. It
existed to turn the sentinel into the cancellation cause, but the write path
now returns io.EOF, which is what gRPC reports on send; the real cause reaches
the caller through the receive side, not the send side. Every cancel sets the
send signal under the same lock, so the loop guard returns io.EOF before
WriteFrame is even reached, and a send woken while parked returns it too. The
only WriteFrame errors left are genuine transport failures, which happen only
when the stream was not terminated, so there is no cancel cause to substitute
and the raw error is correct.
Passing a signal instead of a channel also lets WriteFrame resolve its channel
lazily, only when a producer actually parks, so a stream that never hits
backpressure no longer allocates that channel on every send.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
0 commit comments