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
Improve body buffering/streaming to avoid possible deadlock
It was possible to deadlock request body streaming with
beforeRequest. This could happen because the passthrough handler
creates a request stream (with asStream) ready to send upstream (this
is required, to ensure that's registered before any possible response is
sent, or node can dump the body) but beforeRequest itself isn't called
until the completed body is buffered.
This deadlocked because the stream could hit its high watermark (pausing
the request stream entirely) before the body was buffered. The stream
would never continue, because it wasn't connected to a sink yet, but it
couldn't be connected because beforeRequest needed to run before
creating the upstream connection.
This is resolved through two changes:
* asStream no longer actually streams data - it only reads into asBuffer
for as long as possible (at least until truncation). Real streaming
(and backpressure) only begins once the buffer truncates or a sink
appears.
* Truncation stops the input entirely and delegates entirely to
asStream. This means that backpressure kicks in at this point.
The end result should be that we only store maxSize + highWatermark in
our buffers at any time, applying backpressure for anything else, but
avoid this deadlock before that point by keeping the stream inactive
while buffering is happening. That means if you're just waiting on
waitForCompletedRequest then stream backpressure is not happening.
The only remaining possible deadlock would happen if a handler created a
stream *and started streaming from it* but then paused it so it couldn't
drain fully, and then called waitForCompletedRequest. Don't do that - if
you start streaming, make sure you will finish.
This is all very complicated, but I _think_ this should improve things
significantly.
0 commit comments