Subject: [quicwg/base-drafts] Does QUIC need stream reservation? (#174)

From: Martin Thomson <[email-masked]>
Date: Wed, 18 Jan 2017 14:43:37 -0800

QUIC borrows the concept of stream reservation from HTTP/2.  However, there is a small difference between those state machines in that a reserved stream becomes open when data is sent on it.  HTTP/2 reserved streams become half-closed in this case (basically, only the server can send on a reserved stream).

The reason we have reservation is that we use stream numbers to identify requests at the HTTP mapping.  We reserve the stream number so that we can use its number in the PUSH_PROMISE frame.  That ties the PUSH_PROMISE - which contains a request - to the stream containing the response.  We need to create streams sequentially, so reservation allows us to "create" the stream in the right order and still be able to reference it.

In practice, however, this is a nuisance.  Reserved streams don't count toward concurrency limits and so they represent an unbounded state exposure.  Reserved streams might be created in order, but they can be used in any order.  Of course, this is a minor annoyance at best because there is always application state, and maybe priority information for these streams.

I believe that QUIC has the opportunity to address this annoyance and in the process make the state machine simpler.  If QUIC removed the concept of stream reservation and instead required that application protocols create their correlators for use with talking about future streams, that would greatly simplify things.

For instance, we could remove the promised stream identifier from PUSH_PROMISE.  Instead, the stream that carries a push promise response could start with a frame that identified the PUSH_PROMISE by stream and number: "this stream contains the response for promised request number P on stream N".  Or, we could mint a new PUSH_PROMISE identifier that could be carried at the start of the stream.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/174

---

From: Martin Thomson <[email-masked]>
Date: Wed, 18 Jan 2017 15:03:28 -0800

Oh, one other consideration: we would need to build a way to cancel a push promise, since we could no longer preemptively reset the stream that we were promised.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/174#issuecomment-273630222

---

From: Mark Nottingham <[email-masked]>
Date: Mon, 23 Jan 2017 21:02:35 -0800

Discussed in Tokyo; interest in the room; @martinthomson to come up with a PR.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/174#issuecomment-274710587

---

From: Mike Bishop <[email-masked]>
Date: Mon, 23 Jan 2017 21:17:11 -0800

I'm hesitant to do this, largely because of the race between client trying to reject a push that the server has already created, then needing to reset the stream when/if it arrives.  I'm more inclined to Ian's suggestion in the interim:

- Reservation is a purely local concept - the remote doesn't know that the stream has been reserved until it sees a higher-numbered stream actually get used
- Initiators have to count reserved streams toward their limits.
- Receivers count idle streams up to the highest-ever-seen stream numbers as open

This has the problem that packet reordering can cause the peers to disagree on how many streams are open at the time, but that issue already exists with QUIC regardless of what you do.  (I'll open a separate issue for that.)

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/174#issuecomment-274712247

---

From: Martin Thomson <[email-masked]>
Date: Wed, 25 Jan 2017 13:27:02 -0800

I'll note that @MikeBishop's model here is fairly straightforward, and I'll probably write that up.  It means:
* the reserved state no longer is a first class entry in the state machine
* gaps in an otherwise contiguous sequence of stream numbers implies that the streams in the gap are open, just that you haven't seen a packet on it just yet
* those streams count toward concurrency limits
* this can be used by an endpoint to create space for sending in the future (that is, PUSH_PROMISE)

Note that these streams would not be reserved at the point that a PUSH_PROMISE is received.  The streams would be created when the gap was noticed.  That's really the only difference functionally.

Interesting note: h2 closes streams in a gap, but since we have non-determinism in arrival times, we have to either say nothing about the state of those streams or use this rule.  Since saying nothing leads to fragmentation in the space that a receive allocates for incoming streams, the no-gaps rule works best.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/174#issuecomment-275237994

---

From: ianswett <[email-masked]>
Date: Wed, 25 Jan 2017 14:29:20 -0800

No gaps SGTM.  Open with no data seems equivalent to 'reserved', but doesn't require an extra state.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/174#issuecomment-275253414