Subject: [quicwg/base-drafts] HTTP/3 with strict priorities (#2700)

From: ianswett <[email-masked]>
Date: Tue, 14 May 2019 18:32:17 -0700

You can view, comment on, or merge this pull request online at:

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

-- Commit Summary --

  * HTTP/3 with strict priorities

-- File Changes --

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

-- Patch Links --

https://github.com/quicwg/base-drafts/pull/2700.patch
https://github.com/quicwg/base-drafts/pull/2700.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/2700

---

From: ianswett <[email-masked]>
Date: Tue, 14 May 2019 18:54:52 -0700

@ianswett pushed 1 commit.

378e81964260902fd69f5fc83dfe31e881463923  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/848518b57b64beaba0fb70152188e984524bcc6f..378e81964260902fd69f5fc83dfe31e881463923

---

From: ianswett <[email-masked]>
Date: Tue, 14 May 2019 18:56:41 -0700

d7d4dee132b87dd2e4db4827808c8bfade118cc2  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/378e81964260902fd69f5fc83dfe31e881463923..d7d4dee132b87dd2e4db4827808c8bfade118cc2

---

From: ianswett <[email-masked]>
Date: Tue, 14 May 2019 19:17:55 -0700

2308e69b108313f73ed8206d019c4830e71acfe7  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/d7d4dee132b87dd2e4db4827808c8bfade118cc2..2308e69b108313f73ed8206d019c4830e71acfe7

---

From: ianswett <[email-masked]>
Date: Tue, 14 May 2019 19:22:42 -0700

e933a980c660a0b42c7da711aa34f9c59d297fcd  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/2308e69b108313f73ed8206d019c4830e71acfe7..e933a980c660a0b42c7da711aa34f9c59d297fcd

---

From: ianswett <[email-masked]>
Date: Tue, 14 May 2019 19:27:37 -0700

aa911b9972a0bf377a1ce3f6195f08bd39002b22  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/e933a980c660a0b42c7da711aa34f9c59d297fcd..aa911b9972a0bf377a1ce3f6195f08bd39002b22

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 15 May 2019 05:18:25 -0700

LPardue commented on this pull request.

 When a client initiates a request, a PRIORITY frame MAY be sent as the first
 frame of the stream, creating a dependency on an existing element.  In order to
 ensure that prioritization is processed in a consistent order, any subsequent
-PRIORITY frames for that request MUST be sent on the control stream.  A
-PRIORITY frame received after other frames on a request stream MUST be treated
-as a connection error of type HTTP_UNEXPECTED_FRAME.
+PRIORITY frames for that request MUST be sent on the request stream.

The difficulty here is that you'll need to keep the request stream open (from the client-send side) for as long you want to reprioritize the request. This risks conflicting with the current text in section 5.1 

> An HTTP request/response exchange fully consumes a bidirectional QUIC
   stream.  After sending a request, a client MUST close the stream for
   sending.

That is not insurmountable, you just might need some extra text in the draft to deal with the ripple effects of the changes.

-- 
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/2700#pullrequestreview-237782293

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 15 May 2019 05:34:43 -0700

This seems like a strong alternative candidate for modifying prioritisation without massive deviation from the H2 spec

>      {{prioritized-element-types}}). When sent on a request stream, this MUST be
-    set to `11`.  When sent on the control stream, this MUST NOT be set to `11`.
+    set to `0`.
+
+  D (Dependent On Placeholder):
+  : A one-bit field indicating whether a element depends upon a placeholder

```suggestion
  : A one-bit field indicating whether an element depends upon a placeholder
```

>  {: #element-dependency-types title="Element Dependency Types"}
 
 Note that unlike in {{!RFC7540}}, the root of the tree cannot be referenced
-using a Stream ID of 0, as in QUIC stream 0 carries a valid HTTP request.  The
-root of the tree cannot be reprioritized.
+using 0, so the root of the tree cannot be reprioritized.
 
 The PRIORITY frame can express relationships which might not be permitted based
 on the stream on which it is sent or its position in the stream. These
 situations MUST be treated as a connection error of type HTTP_MALFORMED_FRAME.
 The following situations are examples of invalid PRIORITY frames:
 
 - A PRIORITY frame sent on a request stream with the Prioritized Element Type

Since the list is one bullet point long with this change, you could probably roll this back into prose

-- 
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/2700#pullrequestreview-237785560

---

From: ianswett <[email-masked]>
Date: Wed, 15 May 2019 09:08:57 -0700

e94b1d9b030027fd572209657ff71cd9e4b3fae5  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/aa911b9972a0bf377a1ce3f6195f08bd39002b22..e94b1d9b030027fd572209657ff71cd9e4b3fae5

---

From: Mike Bishop <[email-masked]>
Date: Wed, 15 May 2019 09:30:27 -0700

MikeBishop commented on this pull request.

Overall, I like the design if the working group has the will to restructure this much.  I think you're burying the lede by not discussing what happens when a placeholder has both weighted and unweighted children.  It's at the very bottom of the prioritization section, and it's a major departure from HTTP/2 that should probably be at the top.

I find the idea of simultaneously having a priority and a weight overly complicated.  As an alternative, perhaps this could be a property of the placeholder -- children are served either in sequence or round-robin by weight, but you can't mix.  (And if you need to mix, just put a placeholder of the opposite type as a child.)

> @@ -1099,36 +1096,41 @@ the RST bit set if it detects an error with the stream or the QUIC connection.
 ## Prioritization {#priority}
 
 HTTP/3 uses a priority scheme similar to that described in {{!RFC7540}}, Section
-5.3. In this priority scheme, a given element can be designated as dependent
-upon another element. This information is expressed in the PRIORITY frame
-{{frame-priority}} which identifies the element and the dependency. The elements
-that can be prioritized are:
-
-- Requests, identified by the ID of the request stream
+5.3, but replaces streams depending upon streams with strict priorities and
+placeholders.  In the HTTP/3 priority scheme, a stream can be given a strict
+priority or can be designated as dependent upon a placeholder or the root.

...or weights, apparently?

>  - Pushes, identified by the Push ID of the promised resource
   ({{frame-push-promise}})
 - Placeholders, identified by a Placeholder ID
 
-Taken together, the dependencies across all prioritized elements in a connection
-form a dependency tree. An element can depend on another element or on the root
-of the tree. A reference to an element which is no longer in the tree is treated
-as a reference to the root of the tree. The structure of the dependency tree
-changes as PRIORITY frames modify the dependency links between prioritized
-elements.
-
-Due to reordering between streams, an element can also be prioritized which is
-not yet in the tree. Such elements are added to the tree with the requested
-priority.
+In HTTP/3, stream dependencies that were implicitly encoded by dependencies in
+HTTP/2 are explicitly encoded with strict prioritization.  This simplifies
+priority tree management, eliminates potential new race conditions introduced
+by HTTP/3's multiple streams, and improves framing efficiency with more than
+64 requests.

I'm not sure we need to be explicit about the 64 requests part.  Maybe just say "for long-lived connections"?

 When a prioritized element is first created, it has a default initial weight
-of 16 and a default dependency. Requests and placeholders are dependent on the
-root of the priority tree; pushes are dependent on the client request on which
-the PUSH_PROMISE frame was sent.
+of 16, priority of 16, and a default dependency. Requests and placeholders are

I'm surprised that they have an initial weight, when weight can be omitted.  Shouldn't the default be to have null weight?

 When a prioritized element is first created, it has a default initial weight
-of 16 and a default dependency. Requests and placeholders are dependent on the
-root of the priority tree; pushes are dependent on the client request on which
-the PUSH_PROMISE frame was sent.
+of 16, priority of 16, and a default dependency. Requests and placeholders are
+dependent on the root of the priority tree; pushes are dependent on the client
+request on which the PUSH_PROMISE frame was sent.

...except that your PR removes the ability to depend on streams, so this means push streams start out in an impossible-to-express state.  Not _necessarily_ a problem (we're doing it with the orphan placeholder), but make sure it's deliberate.

 Requests may override the default initial values by including a PRIORITY frame
 (see {{frame-priority}}) at the beginning of the stream. These priorities
 can be updated by sending a PRIORITY frame on the control stream.
 
+Higher priority elements have all available data sent before elements of lower
+priority.  When multiple elements have the same priority, if a weight is
+specified, elements with weights are interleaved.  If a weight is not
+specified, then elements are delivered sequentially and all available data
+from one element is sent before any data from the next.  If a given priority
+level has some elements with weights and some without, the two groups share
+the available bandwidth equally.

How weights and explicit priorities interact probably needs to come at the top of the section, since it's a pretty substantial departure from HTTP/2.

> -    |                |
-    A                A
-~~~~~~~~~~
-{: #fig-pruning title="Example of Priority Tree Pruning"}
-
-In the example in {{fig-pruning}}, `P` represents a Placeholder, `A` represents
-an active node, and `I` represents an inactive node.  In the first step, the
-server discards two inactive branches (each a single node).  In the second step,
-the server condenses an interior inactive node.  Note that these transformations
-will result in no change in the resources allocated to a particular active
-stream.
-
-Clients SHOULD assume the server is actively performing such pruning and SHOULD
-NOT declare a dependency on a stream it knows to have been closed.
+When a placeholder is reparented, given a new weight or given a new strict
+priority, all dependent placeholders and streams are also re-prioritized.

```suggestion
priority, the effective priority of all dependent placeholders and streams is impacted.
```
Just to be explicit that their priorities don't directly change.

-- 
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/2700#pullrequestreview-237930797

---

From: Dmitri Tikhonov <[email-masked]>
Date: Wed, 15 May 2019 13:32:00 -0700

dtikhonov commented on this pull request.

   ({{frame-push-promise}})

The can sentence can be removed: it's an editorial.

-- 
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/2700#discussion_r284438135

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 15 May 2019 14:38:42 -0700

Clarification question: Does the proposed approach allow specifying the optimal ordering that some of us seemed to agree in #2502?

The optimal ordering being:
1. JavaScript and CSS files are sent at first, one by one
2. after that, images are sent with the bandwidth distributed evenly among them

It seems to me that for 2 to happen strictly after 1, a placeholder needs to be allowed to belong to a request stream. However the text in the PR does not seem to allow that (maybe I'm missing something).

-- 
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/2700#issuecomment-492833449

---

From: Mike Bishop <[email-masked]>
Date: Wed, 15 May 2019 21:22:27 -0700

If I've understood the scheme properly, you would achieve that by:
- No weight on the JS/CSS (i.e. deliver each resource all at once)
- All JS/CSS dependent on the same parent; specified priority doesn't necessarily matter unless you want to subdivide
- Another placeholder dependent on the parent with a lower priority than the JS/CSS files
- All images dependent on the second placeholder with equal weights

-- 
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/2700#issuecomment-492911040

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 15 May 2019 21:51:31 -0700

kazuho commented on this pull request.

Would it make sense to change the requirement of the last sentence to something like: "If a given priority level has some elements with weights and some without, those without weights are sent before any of those with weights"?

I suggest this because it would be a simplification. Current text requiring the bandwidth to be evenly split between the two groups essentially suggests implementations to create one more WRR instance - I prefer avoiding that.

I think such a change is fine because I do not think most of the client would use the prioritization scheme in such a way, and because clients that indeed want in fact to split the bandwidth can use placeholders to accommodate 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/pull/2700#discussion_r284538245

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 16 May 2019 06:39:45 +0000 (UTC)

@MikeBishop Thank you for the answer. With your answer in my mind I've reread the PR and maybe it possible to achieve that without using any placeholders? Maybe like:

```
root -+- JS1 (priority=256,weight=N/A)
      +- JS2 (priority=256,weight=N/A)
      +- CSS1 (priority=256,weight=N/A)
      +- CSS2 (priority=256,weight=N/A)
      +- HTML (priority=32,weight=N/A)
      +- image1 (priority=16,weight=16)
      +- image2 (priority=16,weight=16)
      +- image3 (priority=16,weight=16)
      +- image4 (priority=16,weight=16)
```

-- 
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/2700#issuecomment-492938256

---

From: Tatsuhiro Tsujikawa <[email-masked]>
Date: Thu, 16 May 2019 05:00:01 -0700

tatsuhiro-t commented on this pull request.

   Weight:
-  : An unsigned 8-bit integer representing a priority weight for the prioritized
-    element (see {{!RFC7540}}, Section 5.3). Add one to the value to obtain a
-    weight between 1 and 256.
+  : An optional unsigned 8-bit integer representing a priority weight for the
+    prioritized element (see {{!RFC7540}}, Section 5.3). Add one to the value
+    to obtain a weight between 1 and 256.  When absent, indicates the resource
+    should be delivered all at once or not at all.

Server might not have all data in place (e.g., streaming via proxy).  To achieve "delivered all at once or not at all", it seems to me that proxy has to buffer all data, which is impossible if data is unlimited or too large.

-- 
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/2700#pullrequestreview-238345438

---

From: Robin Marx <[email-masked]>
Date: Thu, 16 May 2019 06:28:44 -0700

rmarx commented on this pull request.

   Weight:

Maybe a similar indication as in the HTTP/2 RFC makes sense:

"When absent, indicates the resource should be allocated the full available resources from its parent, as long as it is able to make progress."

-- 
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/2700#discussion_r284705390

---

From: Robin Marx <[email-masked]>
Date: Thu, 16 May 2019 06:52:06 -0700

Thank you for beating me to this Ian :) 

I am a bit unsure about this approach. While it seems to allow @pmeenan's setup, as I mentioned at the bottom of this comment https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491246513, I'm not sure that is really necessary. 

With the existing setup (allowing dependencies on a request stream), we seem to only lose the ability to re-prioritize elements within the same "bucket". E.g., if you're sending a Font file, you cannot have a CSS file interrupt it, if they are both under the same Placeholder (HIGHEST in my example there). I am unsure if this is such a bad thing, since both the Font and CSS are similarly important and both need to be downloaded in full to be applied (iiuc). If you still wanted interruptability, you could add another placeholder "bucket" (e.g., FONTS) to go more fine-grained. 

Either way, the current proposed text in this PR is a bit ambiguous about what happens if you receive a new entry with a higher priority than the current highest-priority element: do you interrupt the current response for the new one? (e.g., you had a FONT of priority 50, it's about 50% done sending, now you get a sibling CSS of priority 60: will that interrupt the FONT? I would assume so). That goes against he "be delivered all at once or not at all" mantra. 

One of the benefits of Pat's scheme imo is that it is easier to implement and doesn't require keeping track of open/closed streams and separate placeholders etc. By integrating this into the tree-based setup here, we are losing that simplicity (also remarked by @MikeBishop earlier here). I also agree with Mike's remark that this type of thing might make more sense as a property of the Placeholder, rather than each individual stream/node.

I am probably missing something here, but it would be good to get some more clarification on what use case we are trying to support exactly (and imo we should wait for some input from @pmeenan (mainly on the importance of reprioritizing within a sequential list) before proceeding much further). 

As a side note: I assume this would be complementary to the Orphan Placeholder in #2690? Because #2502 discusses 2 (imo) separate concepts, and these 2 PRs treat them individually in my perspective. 

-- 
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/2700#issuecomment-493076309

---

From: Patrick Meenan <[email-masked]>
Date: Thu, 16 May 2019 08:29:10 -0700

I'll read through the proposal in a minute but to answer the "interrupt delivery" question, the expectation across the board is yes, lower priority streams will get interrupted by higher priority streams as soon as data for the higher priority stream is available (I'd actually argue that it's critical to be able to interrupt).

-- 
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/2700#issuecomment-493116073

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 16 May 2019 17:41:19 -0700

@rmarx 
> While it seems to allow @pmeenan's setup, as I mentioned at the bottom of this comment #2502 (comment), I'm not sure that is really necessary.

I think that the question.

While I think this would be a simplification for HTTP/3, it would be an additional complexity for HTTP/2+HTTP/3 as a whole. At the moment, prioritization scheme of HTTP/3 allows implementations to reuse the logic of HTTP/2 prioritization (only what's visible on the wire is different).

-- 
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/2700#issuecomment-493277895

---

From: MikkelFJ <[email-masked]>
Date: Fri, 17 May 2019 00:53:25 -0700

If strict interruption is not critical, it would simplify the QUIC API if weights can be applied and updated to active QUIC streams such that the QUIC scheduler can use weighted round robin to decide what to send next without tracking which streams are currently blocked. It would also allow very small streams to complete even if they have low priority, for example small SVC icons. On the other hand, HTTP/3 probably shouldn't start new streams of lower priority while there are higher priority streams still transmitting or ready to be transmitted.

-- 
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/2700#issuecomment-493359026

---

From: Robin Marx <[email-masked]>
Date: Fri, 17 May 2019 01:27:25 -0700

To clarify, I am not saying strict interruption is not critical. I am saying strict interruption **inside a single, sequential queue** is not critical.

As in: CSS/JS should still definitely interrupt images and the small SVG icon should not make progress until higher priority resources are fully fetched. 

The main thing we lost imo when getting rid of exclusive dependencies in practice, was the ability to fully re-prioritize within a sequential list, the way that Chrome is doing its H2 setup (without placeholder, all nodes are daisy-chained). In https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491246513 I did a thought experiment of how we might do Chrome's behaviour with the current text and it comes out very similar. The only thing missing is the ability to interrupt within a single priority "bucket" (represented by a placeholder). My point is that I doubt this is necessary, as I don't feel you want to interrupt e.g., a Font file for a CSS file. And even if you would want that, you could add an extra priority bucket. I am however not very sure this is the case, so that's what I wanted @pmeenan's input on. 

If that specific ability is not very critical, it is my feeling we do not need this change, as it would add much complexity and departure from HTTP/2, while gaining us little. I would be more in favor of providing an extension that just implements Pat's original proposal outside of the main setup (so no tree, nodes, placeholders, etc.). I am perfectly willing to help write such a document btw, @pmeenan ;) 

It is possible that Pat's proposal (and by consequence, this PR) allows additional options that weren't possible in H2 that I haven't considered. That would be a good argument to push forward with this, but I haven't seen a concrete example of those yet. 

-- 
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/2700#issuecomment-493369036

---

From: Robin Marx <[email-masked]>
Date: Fri, 17 May 2019 03:03:38 -0700

Maybe it's a good idea if I prepare some slides with examples of trees in the different proposals for Thursday, to help guide the discussion? 

-- 
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/2700#issuecomment-493399067

---

From: ianswett <[email-masked]>
Date: Fri, 17 May 2019 06:33:17 -0700

efce244c815708810a0ea291fb9e9ac43659f65c  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/e94b1d9b030027fd572209657ff71cd9e4b3fae5..efce244c815708810a0ea291fb9e9ac43659f65c

---

From: Dmitri Tikhonov <[email-masked]>
Date: Fri, 17 May 2019 08:16:47 -0700

> While I think this would be a simplification for HTTP/3, it would be an additional complexity for HTTP/2+HTTP/3 as a whole. At the moment, prioritization scheme of HTTP/3 allows implementations to…

This is an important aspect of this discussion.  Extant HTTP/2 stacks can use the current (ID-20) version of HTTP/3 prioritization with few changes.  Radical departures from it will inevitably result in more work for them -- not just in programming effort, but also to research how to use the new prioritization scheme effectively.

To be adopted, a new prioritization model should be substantially and demonstrably better than the current one. The proponents of new schemes should catalogue use cases (as @rmarx also mentions above) for comparison with the current scheme.

Recent reports (both in clients and servers) indicate that HTTP/2 prioritization is already being leveraged to produce substantial performance benefits.  It would be nice if these solutions could be used in HTTP/3 as well.

-- 
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/2700#issuecomment-493491549

---

From: MikkelFJ <[email-masked]>
Date: Fri, 17 May 2019 08:22:41 -0700

Code reuse from an old spec is IMO not a good basis on which to make design decisions for a new spec, while proven concepts could be.

-- 
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/2700#issuecomment-493493568

---

From: Lucas Pardue <[email-masked]>
Date: Fri, 17 May 2019 08:49:25 -0700

> This is an important aspect of this discussion. Extant HTTP/2 stacks can use the current (ID-20) version of HTTP/3 prioritization with few changes. Radical departures from it will inevitably result…

Which stacks do you have in mind? 

A survey of user agents indicates that the priority trees were designed once and not iterated on. Developers or users have little control to modify behaviour here. 

On the server side, the priority tree is an input into the logic. If the servers' processing is tightly coupled to the input scheme, that would suggest difficulty in trying out alternatives, which is maybe an indicator to the feasible success of prioritisation extensions.

As Cloudflare recently blogged about, our extant HTTP/2 stack has many problems in trying to deliver on the intended design expections. However, a broad set of those problems had nothing to do with the priority tree itself.

Yes, we don't want to throw the baby out with the bathwater. However, we should also be aware that there's going to be a ton of work to determine how HTTP/3 performs in real-world usage scenarios. Predicting the effects of HTTP/3's design on that work is hard.

-- 
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/2700#issuecomment-493503003

---

From: Dmitri Tikhonov <[email-masked]>
Date: Fri, 17 May 2019 10:44:09 -0700

> Code reuse from an old spec is IMO not a good basis on which to make design decisions for a new spec, while proven concepts could be.

I agree.  My point is mostly that one technology already works.

> Which stacks do you have in mind?

I mean mostly browsers.  It is they that have to figure out how to use priorities effectively.  The servers just have to follow what the client says.

> Yes, we don't want to throw the baby out with the bathwater. However, we should also be aware that there's going to be a ton of work to determine how HTTP/3 performs in real-world usage scenarios.…

The logical next step is to make prioritization configurable?

-- 
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/2700#issuecomment-493539428

---

From: ianswett <[email-masked]>
Date: Fri, 17 May 2019 12:16:10 -0700

62139b46ae04df91182e5176b7981d6cc6e6cbd5  Change back to PT bits from a single P bit

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/efce244c815708810a0ea291fb9e9ac43659f65c..62139b46ae04df91182e5176b7981d6cc6e6cbd5

---

From: ianswett <[email-masked]>
Date: Fri, 17 May 2019 12:19:04 -0700

a9dab43cf5dbc3d94eff135f9ed86e999688a8f2  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/62139b46ae04df91182e5176b7981d6cc6e6cbd5..a9dab43cf5dbc3d94eff135f9ed86e999688a8f2

---

From: ianswett <[email-masked]>
Date: Fri, 17 May 2019 19:21:01 +0000 (UTC)

95ab2819ca5c28a2bf4e9d030cb306d5f82137a6  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/a9dab43cf5dbc3d94eff135f9ed86e999688a8f2..95ab2819ca5c28a2bf4e9d030cb306d5f82137a6

---

From: ianswett <[email-masked]>
Date: Fri, 17 May 2019 12:21:53 -0700

c9e7dd6abdcf582826e8250481308f018ab7f304  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/95ab2819ca5c28a2bf4e9d030cb306d5f82137a6..c9e7dd6abdcf582826e8250481308f018ab7f304

---

From: ianswett <[email-masked]>
Date: Fri, 17 May 2019 12:23:11 -0700

0177e4ec25c14f9a30cf18ad908098cb77914831  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/c9e7dd6abdcf582826e8250481308f018ab7f304..0177e4ec25c14f9a30cf18ad908098cb77914831

---

From: ianswett <[email-masked]>
Date: Fri, 17 May 2019 12:31:25 -0700

aaabebdefaf859c960424c0eed1957ef821f13ed  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/0177e4ec25c14f9a30cf18ad908098cb77914831..aaabebdefaf859c960424c0eed1957ef821f13ed

---

From: ianswett <[email-masked]>
Date: Fri, 17 May 2019 12:31:49 -0700

ianswett commented on this pull request.

Thanks for all the excellent suggestions.

Agreed, it's possible I should separate that change from this one.  I know some WG members are fairly unhappy that they can't process PRIORITY frames immediately in cases when the stream hasn't arrived yet, but it's not 100% clear to me that's too painful in practice.

I've now reverted this portion of the change, thanks for the suggestion.

   Weight:

Thanks @rmarx suggestion taken.

 

I added back another one, but it's still a short list.  I believe one more will end up being added, so keeping the structure for now to minimize diffs.

   ({{frame-push-promise}})

Removed.

Agreed, I'll change to 0 weight, which is equivalent to omitting a weight.

Good point, will fix this.

-- 
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/2700#pullrequestreview-237913362

---

From: Lucas Pardue <[email-masked]>
Date: Fri, 17 May 2019 13:28:30 -0700

> I mean mostly browsers. It is they that have to figure out how to use priorities effectively. The servers just have to follow what the client says.

I hypothesise the challenge there will be how to manage prioritisation of different resources on different hosts being fetched using different protocols. 

-- 
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/2700#issuecomment-493589246

---

From: ianswett <[email-masked]>
Date: Fri, 17 May 2019 13:31:33 -0700

Thanks for the follow-up discussion. I think some slides for the interim would be helpful, and I'm happy to work on them with @rmarx or anyone else who's there and wants to contribute.

On the matter of re-using HTTP/2 code, I think we've already departed enough that major changes are going to be necessary for many implementations.  For example, I believe Chrome would be best off moving to using a linked list of placeholders for it's priority buckets as @rmarx described.

In terms of complexity, this can be simplified some and I believe still represent the full functionality of HTTP/2.  In particular, strict priorities in placeholders or placeholders depending upon placeholders could be removed, since they're largely duplicative.

On a personal note, I'd prefer to adopt something closer to Patrick Meenan's proposal, but on that thread there was the theoretical use case of a proxy that wants to fairly share connectivity to an ORIGIN.  It doesn't appear anyone's using that, so I'd prefer to jettison it, but I'm trying to find a proposal we can agree on.

One thing to appreciate is that HTTP/2 is head-of-line blocking, but HTTP/3 is not, so waiting two RTTs before pruning may result in much more frequent issues in HTTP/3.  I'd recommend 3 * PTO or some much longer value.  I see changing HTTP/3's priority scheme similar to changing from HPACK to QPACK.  We need to acknowledge that removing HoL blocking is going to cause issues(that's why we removed exclusive prioritization) and make adjustments.  We've already made two large-ish changes, but we still don't have something with completely deterministic behavior.  In other parts of the transport(and QPACK), we've balked at pathological edge cases like that proposed in #2690, so it seems inconsistent to say it's OK for this one case.

-- 
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/2700#issuecomment-493590118

---

From: ianswett <[email-masked]>
Date: Fri, 17 May 2019 13:44:14 -0700

@dtikhonov "My point is mostly that one technology already works." - I'll specifically disagree with this point.  HTTP/2 has been an RFC for 4 years now and according to Patrick Meenan's surveys, a huge fraction of servers don't support HTTP/2 priorities and clients have somewhat odd usage patterns, with Chrome specifically trying to re-create strict priorities and Edge ignoring them entirely.

The complexity has also kept HTTP/2 priorities out of the web APIs, because it's clear the full functionality is far too complex for web developers and it's hard to agree upon what should be surfaced.

The target should be something the majority of implementations will implement, even if it's not their ideal solution.

-- 
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/2700#issuecomment-493593668

---

From: ianswett <[email-masked]>
Date: Fri, 17 May 2019 16:16:04 -0700

4124932b0f6d374fd9849d85e9c3c1ee9fe26e2d  Update draft-ietf-quic-http.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2700/files/aaabebdefaf859c960424c0eed1957ef821f13ed..4124932b0f6d374fd9849d85e9c3c1ee9fe26e2d

---

From: Igor Lubashev <[email-masked]>
Date: Sat, 18 May 2019 07:51:42 -0700

igorlord commented on this pull request.

+Higher priority elements have all available data sent before elements of lower
+priority.  When multiple elements have the same priority, if a weight is
+specified, elements with weights are interleaved.  If a weight is 0, either
+because it is the default weight or it was not specified, then elements are
+delivered sequentially and all available data from one element is sent before
+any data from the next.  If a given priority level has some elements with
+weights and some without, the two groups share the available bandwidth equally.

You can have 10 elements with weights at some priority level, sharing bandwidth.  When you add a single element to that priority level without a weight, the bandwidth for the 10 elements is halved.  This does not seem right.

```suggestion
weights and some without, the two groups share the available bandwidth proportionally to the number of elements in each group.
```

-- 
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/2700#pullrequestreview-239201115

---

From: MikkelFJ <[email-masked]>
Date: Sat, 18 May 2019 07:54:38 -0700

mikkelfj commented on this pull request.

I suggest looking at rmarx proposal.

-- 
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/2700#discussion_r285345165

---

From: ianswett <[email-masked]>
Date: Sun, 19 May 2019 17:24:58 -0700

Good point @igorlord This was reflecting what Patrick Meenan wrote up, but I agree that it's not clear it's the right option.

Personally, I would prefer removing weights from streams and only having one bit to declare that this resource is incrementally useful.  

-- 
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/2700#discussion_r285404879

---

From: Robin Marx <[email-masked]>
Date: Mon, 20 May 2019 09:19:20 -0700

Turns out I had misunderstood the intent of this PR with regards to @pmeenan's setup and how to recreate the following image. Turns out it's really quite brilliant! 

![pmeenan's approach](https://raw.githubusercontent.com/pmeenan/http3-prioritization-proposal/master/images/sample.svg?sanitize=true)

For others who might not have figured it out:

@ianswett proposes to use odd numbered priority values (e.g., 127, 125, ...) to represent concurrency level 3, and even numbered priority values (e.g., 126, 124, ...) to represent concurrency levels 2 and 1.
For example:
127 = concurrency 3
126, no weight = concurrency 2
126, weight = concurrency 1

This allows the whole thing to be represented without a single placeholder (which I didn't understand before now)! That is immensely powerful, while also allowing normal placeholders.

It would also allow resolving #2690 in the same way as proposed in #2723 : just make priority 0, no weight the default for new nodes! 

We're not sure yet about streams-upon-streams dependencies and how this mixes with the placeholder approach etc. but it seems this PR could be the one we were looking for. We will iterate on this and create some example schema's. 

-- 
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/2700#issuecomment-494055797

---

From: Igor Lubashev <[email-masked]>
Date: Mon, 20 May 2019 09:52:43 -0700

@rmarx, I would not say that odd priority values _represent_ odd concurrency level 3.  You could implement @pmeenan's "concurrency level 3" that way.  But the idea is that you do not need "concurrency level 3" as a special case to think about.

There are just two criteria:

1. Priorities:  Elements of the higher priority 100% preempt elements of the lower priority.

2. Concurrency: Elements of the same priority share bandwidth.  Serial elements need to be downloaded to completion one at a time, while concurrent elements need to be downloaded concurrently.  There is still a question of how serial and concurrent elements share bandwidth.  There is a proposal that concurrent elements get 50% of the bandwidth as a group.  The alternative is that concurrent elements group gets a percentage proportional to the number of concurrent elements in at that priority level. Both of these alternatives seem "hacky" as they possible do not give the client sufficient control for bandwidth sharing.  I have some proposal and will share it on the list (the PR comment does not seem like the right place for it).

-- 
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/2700#issuecomment-494067457

---

From: Tatsuhiro Tsujikawa <[email-masked]>
Date: Tue, 21 May 2019 08:45:17 +0000 (UTC)

If we give up sequential stuff, it becomes quite simple:

(quoting from the previous comment)
1. Priorities: Elements of the higher priority 100% preempt elements of the lower priority.
2. Concurrency: Elements of the same priority share bandwidth.

And there is no 0 weight or special weight.   Nodes share bandwith according to their weight if they are under the same priority.

-- 
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/2700#issuecomment-494299103

---

From: ianswett <[email-masked]>
Date: Tue, 21 May 2019 02:11:10 -0700

This discussion is a mix of editorial(ie: what does this scheme actually accomplish/specify?) and non-editorial(ie: Why do I think this is good/bad) commentary.

I apologize for setting a poor example, but please do try to direct non-editorial comments to the list or issue and I'll do the same.  Given @dtikhonov already started an email thread about this PR, I think the list makes the most sense.

-- 
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/2700#issuecomment-494308304

---

From: Robin Marx <[email-masked]>
Date: Thu, 23 May 2019 00:41:33 -0700

> It would also allow resolving #2690 in the same way as proposed in #2723 : just make priority 0, no weight the default for new nodes!

This is not entirely correct sadly... 
Main example is Safari/Edge behaviour: all nodes dependent on the root, setting explicit weights (but no priorities!).

If un-prioritized/default nodes are added with priority 0 + weight 0, they would share the bandwidth 50/50 with the weighted nodes, making this default even worse than the HTTP/2 of adding the nodes with weight 16... 

Potential solution is to add them with priority=0,weight=1, but then they will still get some part of the bandwidth (how much depends on the weights of other things) and we are again back to round-robin (which we don't want, we want FIFO in the default case). 

So, other solutions:
- Nodes without priorities and without weights (default): priority=0, weight=0. Nodes without priorities but WITH weights (explicit behaviour): priority=1,weight=incoming
- Special priority level -1 ("implicit orphan placeholder")
- Explicit orphan placeholder (#2690) (BUT then we can't implement this setup without any placeholders at all, which is possible at the moment)

-- 
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/2700#issuecomment-495104771