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

Mike Bishop <> Wed, 15 May 2019 16:30 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id AC8A1120182 for <>; Wed, 15 May 2019 09:30:31 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -8.011
X-Spam-Status: No, score=-8.011 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, MAILING_LIST_MULTI=-1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H2=-0.001, SPF_PASS=-0.001, T_DKIMWL_WL_HIGH=-0.01] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (1024-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id CDT7pVx54L0M for <>; Wed, 15 May 2019 09:30:29 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 0BE64120178 for <>; Wed, 15 May 2019 09:30:29 -0700 (PDT)
Date: Wed, 15 May 2019 09:30:27 -0700
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=pf2014; t=1557937827; bh=0q0HR0Ci4DLJ+nPY+xHiAyVwDkiSOQ6nMIbiV56d54Q=; h=Date:From:Reply-To:To:Cc:In-Reply-To:References:Subject:List-ID: List-Archive:List-Post:List-Unsubscribe:From; b=Wr8gkjBIGjK6TqIZElInTxPk/E75K70CFYQn8fMmGumK7SbGNQzMeHG7PTfZ83Z1j CjVFWBPScUAkZAj8dfwCTiOE/c+NSvAh8p4H9zplDVas822Hf1TJwetatSfpLQUbFf lVenGzXBgTmDQvRVbo3B0F0M2CuWeYltvtMfpBbo=
From: Mike Bishop <>
Reply-To: quicwg/base-drafts <>
To: quicwg/base-drafts <>
Cc: Subscribed <>
Message-ID: <quicwg/base-drafts/pull/2700/review/>
In-Reply-To: <quicwg/base-drafts/pull/>
References: <quicwg/base-drafts/pull/>
Subject: Re: [quicwg/base-drafts] HTTP/3 with strict priorities (#2700)
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="--==_mimepart_5cdc3ea32614d_32e93fd11d4cd96053259"; charset="UTF-8"
Content-Transfer-Encoding: 7bit
Precedence: list
X-GitHub-Sender: MikeBishop
X-GitHub-Recipient: quic-issues
X-GitHub-Reason: subscribed
X-Auto-Response-Suppress: All
Archived-At: <>
X-Mailman-Version: 2.1.29
List-Id: Notification list for GitHub issues related to the QUIC WG <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Wed, 15 May 2019 16:30:32 -0000

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
 - 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
-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
+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
-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.

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: