Subject: [quicwg/base-drafts] HTTP/3 reserved stream practical credits (#4349)

From: Lucas Pardue <[email-masked]>
Date: Wed, 11 Nov 2020 03:15:38 -0800

Relates to https://tools.ietf.org/html/draft-ietf-quic-http-32#section-6.2. 

The section is pretty exhaustive already. However, someone taking things too literally might just advertise credit for the bare minimum unidirectional streams. If that is the case, it restricts our ability to grease reserved streams and catch problems early.

For example, quiche has all the logic in place to send reserved streams but will always send the mandatory control streams first. Clients that are overly conservative with credits will never get tested.

I wonder if we should more strongly recommend providing +1 credit on the top of control streams.

-- 
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/4349

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 11 Nov 2020 03:49:16 -0800

I think the question is if we have to grease a receiver that only accepts three unidirectional streams, knowing that the specification states that it can assume that the sender will open the three critical streams before opening others.

The argument for status quo would be that such a receiver has refused to provide extensibility, and therefore that it does not have to be greased.

-- 
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/4349#issuecomment-725378936

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 11 Nov 2020 04:19:28 -0800

The text is careful to say that an endpoint won't necessarily add any more credits. In quiche, we model stream limits as concurrency limits, so an application that sets a value of e.g. 3 will only add more credit when a stream closes, which typically doesn't happen because the control streams are opened first and not closed.

 > The argument for status quo would be that such a receiver has refused to provide extensibility, and therefore that it does not have to be greased.

This is my concern. There's not a way to opt out  explicitly. A peer has to provide credits and has to ignore unknown extensions. My endpoint can use credits as it wishes. If I choose not to create control streams first I might hurt my application. So the incentive is not to exercise our greasing capabilities, which is not great.

Theres a possible risk here that implementions don't gear themselves up for draining or resetting reserved streams. That might interfere with things like flow control in unexpected ways, perhaps causing interop side effects that are hard to detect or fix in the wild.

-- 
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/4349#issuecomment-725392000

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 11 Nov 2020 15:16:50 -0800

I think the argument for status quo are that:
* There's no reason to grease receivers limiting number of incoming unidirectional streams *in total* to three. None of the three unidirectional streams  are to be drained or reset.
* If the receiver provides additional room (either through TP.initial_max_streams_uni or through MAX_STREAMS frames), then the sender can grease.

So I do not think that we are in bad shape. That said, I do agree that it is a bit complex, and I would not oppose to changing the requirement to "receivers MUST be capable of receiving data through three unidirectional streams concurrently."

-- 
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/4349#issuecomment-725714555

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 11 Nov 2020 15:26:48 -0800

I think I'd be happy with just a "SHOULD at least 4", but I could also live with doing nothing.

-- 
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/4349#issuecomment-725719328

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 11 Nov 2020 15:37:54 -0800

IIRC we had a discussion regarding if endpoints have to allow 3, or if the limit can be lower to reduce memory pressure on endpoints.

Recommending 4 goes above that, without having the capability of greasing all receivers. And the sender's logic for greasing is complex.

If we change the text to "MUST do at least there unidirectional streams concurrently," then there would be no issue regarding memory pressure. It would be possible to grease all receivers. And the sender's logic can be simple, assuming that the clients that need performance would do at least 4.

-- 
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/4349#issuecomment-725723221

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 11 Nov 2020 15:46:46 -0800

Oh I missed the nuance of your concurrency statement, sorry. That could work but I wonder what others think the impact might be. We don't have much interop testing coverage in this area.

-- 
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/4349#issuecomment-725727002

---

From: Mike Bishop <[email-masked]>
Date: Tue, 17 Nov 2020 02:02:53 -0800

I feel like the current text covers this adequately.  Recipients MUST permit at least three, and senders SHOULD initiate the required ones first.  SHOULD, by definition, means that it's not strictly mandatory but things could get dicey if you don't.  You're describing the way in which it gets dicey.

Otherwise stated, a receiver that has no support for unidirectional streams beyond control and QPACK won't get greased.  A receiver that wants to add any feature that uses unidirectional streams is going to encounter grease streams and will have to deal with them properly.  I'm okay with that balance.

-- 
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/4349#issuecomment-728823119

---

From: Lucas Pardue <[email-masked]>
Date: Tue, 17 Nov 2020 05:24:09 -0800

Section 6.2 says:

> To avoid blocking, the transport parameters sent
   by both clients and servers MUST allow the peer to create at least
   one unidirectional stream for the HTTP control stream plus the number
   of unidirectional streams required by mandatory extensions (three
   being the minimum number required for the base HTTP/3 protocol and
   QPACK)

and

> Note that an endpoint is not required to grant additional credits to
   create more unidirectional streams if its peer consumes all the
   initial credits before creating the critical unidirectional streams.
   Endpoints SHOULD create the HTTP control stream as well as the
   unidirectional streams required by mandatory extensions (such as the
   QPACK encoder and decoder streams) first, and then create additional
   streams as allowed by their peer.

The second paragraph is a bit sweeping. Instead of "consumes all" it really should say "consumes any". 

Perhaps we can argue about whether reserved streams are mandatory to implement or not but that seems self-defeatist. I will point out though that closing reserved streams is one our recommended methods of exercising reserved error codes. 

-- 
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/4349#issuecomment-728924016

---

From: Mike Bishop <[email-masked]>
Date: Tue, 24 Nov 2020 15:29:08 -0800

As we just discussed, my inclination is to do nothing here.  This is a RFC 6919-style REALLY SHOULD, e.g. it's not quite a MUST, but you're allowed to shoot yourself in the foot if you want.  The text already explains what endpoints should do and why, so I think we're covered.

-- 
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/4349#issuecomment-733291939

---

From: Kazuho Oku <[email-masked]>
Date: Tue, 24 Nov 2020 15:35:29 -0800

I am fine with keeping status quo. It is a bit complex and not ideal (as stated above, I think there is a better way), but it works, and is well-documented.

-- 
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/4349#issuecomment-733294200

---

From: Lucas Pardue <[email-masked]>
Date: Tue, 24 Nov 2020 15:36:53 -0800

I am happy to close this with no action. Marking as proposal-ready.

-- 
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/4349#issuecomment-733294708