QUIC streams abstraction #783
Labels
-transport
design
An issue that affects the design of the protocol; resolution requires consensus.
has-consensus
An issue that the Chairs have determined has consensus, by canvassing the mailing list.
From mailing list thread: Several open issues (#485,#184,#758) come down to how you conceive of the API a QUIC implementation will expose. Two basic ones have been suggested:
TCP Stream sockets. These only support signaling “orderly” closing of the write direction. Closing of the read direction can only be done via close(), but that may leave the write direction in an undefined state (writing will complete, unless there was unread data in the read buffer or any data is received after close – see RFC 1122 4.2.2.13 $3).
A POSIX pipe pair. Connected pipes are very clean (‘symmetric’) abstractions, and they communicate close events (you close the ‘write’ pipe, ‘read’ pipe get EOS; you close the ‘read’ pipe, ‘write’ pipe gets an exception).
My mental model has been (2): a stream/stream-pair consists of an InputStream and an OutputStream; you can read on one, you can write on the other. For the write stream, you can write your data to completion and close the stream, or you can decide to abort writing. The wire expressions of these are FIN and RST_STREAM, respectively. For the read stream, you can read the incoming data to the end or you can abort reading and discard the remainder of the stream; the wire expression of this would be flow control updates or STOP_SENDING, respectively. On the other side, receipt of a RST_STREAM surfaces as a read error and receipt of a STOP_SENDING surfaces as a write error. (@janaiyengar commented that in this mental model it might be clearer to call the frames WRITE_ABORT and READ_ABORT.)
#485 suggests that streams only close by application action; there would never be a write error surfaced to the application unless the underlying transport went away entirely. Instead, as in #758, it’s the responsibility of the application protocol to communicate (on another stream, in this case) that you should abort writing, even if you’ve already written to completion, and then to do so. That implies that the application needs the ability to return to streams on which it’s done writing, in case it’s later asked to go back and reset them.
Much of our discussions around unidirectional streams, stream state transitions, etc. including the question of whether STOP_SENDING belongs at the transport layer, stem from the fact that we all have different implicit mental models of the functional surface QUIC exposes. Perhaps we should take a step back and agree on that first, as I believe Christian has suggested in the past?
The text was updated successfully, but these errors were encountered: