wasi-http icon indicating copy to clipboard operation
wasi-http copied to clipboard

outgoing-body flush behaviour states

Open guybedford opened this issue 2 years ago • 3 comments

As far as I can tell, outgoing-body's stream can exist in two different states:

  1. unattached to the http request, before the request is made - all writes buffer, and flush is effectively a no-op.
  2. attached to the outgoing http request after it has been made - in this state, flush functions correctly.

In state (1), does the subscribe just fail if we exceed the high watermark? Or is the high watermark functionality also disabled?

Effectively, does that mean that a transition from state (1) to state (2) change it from permitting writes over the high watermark to not?

guybedford avatar Nov 23 '23 19:11 guybedford

The specific issue I hit here was that blocking-write-and-flush wasn't functioning correctly in this implementation due to the stream being unflushable before it has been attached to the http request.

guybedford avatar Nov 23 '23 19:11 guybedford

Just discussed this with @elliottt -

In case 1, we don't want to change the meaning of flush to mean nothing. Instead, calling flush should make the body stream not ready for writing until the request is sent successfully. A call to blocking-flush or blocking-write-and-flush would block forever, so in that case implementations should trap. (This is a particular special case where the wasi-http state of the body, as well as the state of the stream, would be required to determine that the implementation should trap, so we won't require it outright because that might be too difficult to implement in some cases - instead, those calls can hang forever, which is also correct but a worse DX.)

One valid implementation of the body stream is permitting no buffering at all, so in state 1 it would never be write ready, and in state 2 it would only become write ready for whatever the underlying network layer buffers. That isn't a very realistic implementation, though, so we expect most implementations will permit some amount of buffering in both states 1 and 2, where once that buffering is full check-write returns 0 until the buffer is emptied. In state 1, either filling the buffer or calling flush will make the check-write return 0 until the body is sent and emptied, and in state 2 it would still need the network layer to empty it.

pchickey avatar Nov 27 '23 19:11 pchickey

This sounds like a sensible direction and the right set of tradeoffs to make to me.

guybedford avatar Nov 28 '23 22:11 guybedford