Subject: [quicwg/base-drafts] Add further guidance related to unidirectional stream TPs (#2612)

From: Lucas Pardue <[email-masked]>
Date: Fri, 12 Apr 2019 04:11:24 -0700

This goes someway to fixing #2559 and #2589.

Setting low values for unidirectional stream transport parameters means that HTTP/3 connections get stuck early. Although client and server can dance around, sending *BLOCKED frames and increasing limits, we should clearly highlight the problem and suggest some sensible, bare minimum, values. 
You can view, comment on, or merge this pull request online at:

  https://github.com/quicwg/base-drafts/pull/2612

-- Commit Summary --

  * Add further guidance related to unidirectional stream TPs

-- File Changes --

    M draft-ietf-quic-http.md (15)

-- Patch Links --

https://github.com/quicwg/base-drafts/pull/2612.patch
https://github.com/quicwg/base-drafts/pull/2612.diff

-- 
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/pull/2612

---

From: ianswett <[email-masked]>
Date: Fri, 12 Apr 2019 07:36:20 -0700

ianswett commented on this pull request.

> @@ -321,8 +321,19 @@ defined in this document: control streams ({{control-streams}}) and push streams
 ({{push-streams}}).  Other stream types can be defined by extensions to HTTP/3;
 see {{extensions}} for more details.
 
-Both clients and servers SHOULD send a value of three or greater for the QUIC
-transport parameter `initial_max_uni_streams`.
+The performance of HTTP/3 connections in the early phase of their lifetime is
+sensitive to the creation and exchange of data on unidirectional streams.
+Endpoints that set low values for the QUIC transport parameters
+`initial_max_uni_streams` and `initial_max_stream_data_uni` will increase the
+chance that the remote peer reaches the limit early. In particular, the value
+chosen for `initial_max_uni_streams` should consider that remote peers may wish
+to exercise reserved stream behaviour ({{stream-grease}}). Limits can be
+increased post handshake at the cost of additional RTT, for example by
+exchanging `STREAMS_BLOCKED` and `MAX_STREAMS` QUIC frames. To reduce the

STREAMS_BLOCKED has no actual effect, it's just informative, so I don't think it's wise to mention it here.

-- 
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/pull/2612#pullrequestreview-226117152

---

From: Lucas Pardue <[email-masked]>
Date: Fri, 12 Apr 2019 15:36:13 +0000 (UTC)

LPardue commented on this pull request.

That's a fair point. However, practically speaking, if a peer spends credit legitimately and needs more, how does it get it?

We're seeing various HTTP/3 issues around getting blocked by conservative initial values, and there is little guidance on ways to mitigate this happening. If the answer is to aggressively dole out credit, it kind of devalues having limits.

-- 
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/pull/2612#discussion_r274960237

---

From: ianswett <[email-masked]>
Date: Fri, 12 Apr 2019 15:39:02 +0000 (UTC)

The receiver should know when all the flow control credit is used(ie: it knows the current max and it knows the amount used in order to enforce limits), so when it gets to or close to 0, it should know the peer is unable to send.

In practice, the current text advises providing enough window for 2RTTs I believe, which is reasonably generous.

-- 
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/pull/2612#discussion_r274961367

---

From: Lucas Pardue <[email-masked]>
Date: Fri, 12 Apr 2019 15:57:57 +0000 (UTC)

Sorry I should have been more specific, I was speaking about the number of uni streams not data. If the server gives the client initial uni streams value of 1, and the client uses up, what should the server do in the sense of upping the unidirectional stream limit? Not giving sufficient unidirectional streams will cause all sorts of annoying issues at the start of a H3 connection.

> In practice, the current text advises providing enough window for 2RTTs I believe, which is reasonably generous.

The problem is that the flow control credit starts at 0 if not specified. So, without some sensible guidance for an initial value, if a remote peer initiates a new unidirectional stream, it then needs to wait for the the local peer to send a MAX_DATA of _some_ value. Again this is pretty naff when all you are trying to do is create a HTTP/3 Control 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/pull/2612#discussion_r274968781

---

From: Marten Seemann <[email-masked]>
Date: Fri, 12 Apr 2019 17:28:33 -0700

marten-seemann commented on this pull request.

There's nothing you can do to force a peer to allow more streams. If a peer continues to misbehave, all you can do is close the connection.
STREAMS_BLOCKED is just a debugging frame, so I agree with @ianswett that we should remove it from this 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/pull/2612#discussion_r275096535

---

From: Lucas Pardue <[email-masked]>
Date: Fri, 12 Apr 2019 17:36:43 -0700

I'm happy to take it out. However, I wouldn't call it misbehaviour to exercise protocol features. The unidirectional stream extension capabilities seem dead on arrival if there is no way for either peer to express their intent.

-- 
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/pull/2612#issuecomment-482760465

---

From: Kazuho Oku <[email-masked]>
Date: Sun, 14 Apr 2019 20:27:30 -0700

kazuho commented on this pull request.

-Both clients and servers SHOULD send a value of three or greater for the QUIC
-transport parameter `initial_max_uni_streams`.
+The performance of HTTP/3 connections in the early phase of their lifetime is
+sensitive to the creation and exchange of data on unidirectional streams.
+Endpoints that set low values for the QUIC transport parameters
+`initial_max_uni_streams` and `initial_max_stream_data_uni` will increase the
+chance that the remote peer reaches the limit early. In particular, the value
+chosen for `initial_max_uni_streams` should consider that remote peers may wish
+to exercise reserved stream behaviour ({{stream-grease}}). Limits can be
+increased post handshake at the cost of additional RTT, for example by
+exchanging `STREAMS_BLOCKED` and `MAX_STREAMS` QUIC frames. To reduce the
+possibility of this situation occuring, both clients and servers SHOULD send a
+value of three or greater for the QUIC transport parameter
+`initial_max_uni_streams`, and a value of eight or greater for the QUIC
+transport `initial_max_stream_data_uni`.

While I understand the motivation to suggest something for `initial_max_stream_data_uni`, 8 bytes sounds strangely small.

I'd argue that we should recommend a value that is greater than the size of SETTINGS frames that most endpoints would send. Also, considering the fact that QUIC endpoint needs to be capable of processing at least one full-sized packet at a time, I do not think that even the most restricted endpoints would set `initial_max_stream_data_uni` below one MTU.

Therefore, I might propose something like "SHOULD be at least 1,024 bytes."

-- 
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/pull/2612#pullrequestreview-226441557

---

From: Lucas Pardue <[email-masked]>
Date: Mon, 15 Apr 2019 02:50:21 -0700

8 bytes gives just enough data to see what the stream type is before committing to receiving any further data. However, I also agree that such a low value in practice will not fix the issues around blocking, so I'll accept your suggestion. 

-- 
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/pull/2612#discussion_r275285157

---

From: Lucas Pardue <[email-masked]>
Date: Mon, 15 Apr 2019 02:51:54 -0700

@LPardue pushed 1 commit.

3dfb77d98acaa24c41937e6ced558371bc717449  Ian and Kazuho's suggestions

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2612/files/bc30517834cb75f96912785edbaf7c1b5d1b3fce..3dfb77d98acaa24c41937e6ced558371bc717449

---

From: Jana Iyengar <[email-masked]>
Date: Wed, 17 Apr 2019 11:03:09 -0700

janaiyengar approved this pull request.

A minor nit, but LGTM otherwise.

> @@ -321,8 +321,17 @@ defined in this document: control streams ({{control-streams}}) and push streams
 
-Both clients and servers SHOULD send a value of three or greater for the QUIC
-transport parameter `initial_max_uni_streams`.
+The performance of HTTP/3 connections in the early phase of their lifetime is
+sensitive to the creation and exchange of data on unidirectional streams.
+Endpoints that set low values for the QUIC transport parameters
+`initial_max_uni_streams` and `initial_max_stream_data_uni` will increase the
+chance that the remote peer reaches the limit early and becomes blocked. In
+particular, the value chosen for `initial_max_uni_streams` should consider that
+remote peers may wish to exercise reserved stream behaviour ({{stream-grease}}).
+To reduce the likelihood of blocking, both clients and servers SHOULD send a
+value of three or greater for the QUIC transport parameter
+`initial_max_uni_streams`, and a value of 1,024 or greater for the QUIC
+transport `initial_max_stream_data_uni`.

```suggestion
transport parameter `initial_max_stream_data_uni`.
```

-- 
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/pull/2612#pullrequestreview-227911387

---

From: Lucas Pardue <[email-masked]>
Date: Thu, 18 Apr 2019 02:51:02 -0700

d3a6944008407ae75170056d7189254905149280  Jana's fix

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2612/files/71f84456937b9d0012c5ecb1ed04fbcc43246adc..d3a6944008407ae75170056d7189254905149280

---

From: Mike Bishop <[email-masked]>
Date: Thu, 18 Apr 2019 11:25:40 -0700

MikeBishop approved this pull request.

Realistically, I think an implementation ought to have a higher number than three here, but the actual requirement for interop will be three much of the time, so I think this is good guidance.  Note that STREAM_BLOCKED doesn't get sent over and over -- if the peer decides not to give you more credit and that means you can't use your extensions, tough luck.

-- 
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/pull/2612#pullrequestreview-228438828

---

From: Mike Bishop <[email-masked]>
Date: Thu, 18 Apr 2019 11:26:17 -0700

Merged #2612 into master.

-- 
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/pull/2612#event-2286542266