Re: Concerns about HTTP/2 Priority

Hi Martin,

On Mon, Nov 3, 2014 at 3:06 PM, Martin Thomson <martin.thomson@gmail.com>
wrote:

> On 3 November 2014 14:16, Mark Nottingham <mnot@mnot.net> wrote:
> The change:
>   Make it so that PRIORITY can be sent on a stream in ANY state.
>   i.e., change so that PRIORITY is permitted in the "idle" state.
>

The kludge is this: you allow a single request from each client at
> your intermediary to establish a node in the dependency tree that is
> subsequently used as an anchor for all their requests in place of
> stream 0.  Since this node will live for some time past the lifetime
> of the initial request, you can treat this as a new root for that
> client.  You can periodically shift which stream you use as an anchor
> if you are concerned about an old stream being garbage collected for
> being too old, even though it is still in use.
>
> That could address the intermediation case, which I think was the
> important one.  Being able to prioritized unused streams would of
> course make it marginally easier.
>
> If you allow the prioritization of unused streams, you can create
> nodes in the dependency tree that can be used to form pseudo-groups.
> These could easily address the intermediation concern.  It doesn't
> perfectly address the "all the JS before all the CSS" scenario, but
> Mark's note there about the server knowing things about priority
> applies.  A robust scheme that properly addressed that case would not
> be as trivial a change.
>
> Here's a second kludge that relies (a little more) on unused streams
> with priority: if JS has to come before all CSS and you have three of
> each, then:  Send requests for all the JS with as high a weighting as
> you feel you can use.  Then, prioritize a new unused stream with the
> same dependency as all the JS, but with very low weight (i.e., 1).
> CSS requests can hang off that low weight stream.  Any server with any
> sense will then avoid spending cycles on the CSS unless it is blocked
> on the JS.
>

I like the idea.  I've gotten hung up in the past thinking about what
happens when all but the unused streams get closed.  Assume unused streams
X, Y, Z and active streams A, B, C:

{X,Y} -> 0
A -> X
Z -> Y
{B, C} -> Z

In the past I've assumed depth in the tree would somehow factor into
resource allocation, but as you pointed out, distribution of resources down
the tree would do the right thing.  50% of resources would be allocated to
A, 25% to B, and 25% to C, which is correct.  (This example is
approximately the intermediation case, where X and Y are created by the
proxy and Z is created by one of the clients.)

My current understanding (which is suspect - I'm sick and my head feels
like a cotton ball), one unused stream of weight 1 per priority level,
under the assumption that servers wouldn't bother spending any resources on
streams of weight 1, would almost perfectly solve both the proxy use case
and the group priorities use case.

Assuming garbage collection of unused streams is solved, I would support
this protocol tweak.  It's not as good as Osama's proposal, but it's better
than what's currently drafted.  :)

As far as I can tell, this second kludge is more difficult to get
> right without the change I suggest, but it's not impossible to get
> something approximating it.
>
> On balance, I'm not sure that we're going to get much without actual
> experience with any scheme we propose, so I don't think that big
> changes are going to be worthwhile.  Well, unless a well-researched
> and extensive study suddenly manifests itself, that is.
>

> I'm not even sure if the tweak above is worth doing, except that it
> makes the scheme slightly more flexible, making the proxy case easier
> to solve.
>

It's up to you and the working group to decide what the right path forward
is, of course, but the "group priority" use case isn't hypothetical to us:

We built our content pipeline architecture under the assumption that we can
efficiently make hundreds and sometimes thousands of HTTP requests to a
server (~Varnish) where the only contended resource is the customer's
bandwidth.  Having fine-grained control over stream priorities would give
us the ability to reduce actual load times from ~40 seconds to ~35 because
we could treat low-priority requests much less conservatively.

The importance of HTTP/2's priority extends beyond the protocol itself.

Ideally, an application would issue ALL of its requests right away.  Any
responses, even low-priority responses, that are cached by the browser
would be returned to the application right away.  But if there's no way to
specify priority at the web API level (and trust that it's mapped
accurately to the underlying protocol), then this is dangerous, because
low-priority responses might impede high-priority responses, increasing
overall load time.

To be honest, even SPDY's 3 bits of priority would be plenty sufficient for
our case, but WHATWG does not seem amenable to adding any priority API to
the web platform until HTTP/2's semantics are defined, as the web API
should be forward-looking.

Perhaps the right thing to do is adopt Martin's unused stream workaround
into HTTP/2, leave the option for adopting Osama's priority design as an
extension or HTTP/2.1 or HTTP/3 once there is sufficient production
experience, and base the WHATWG web API on numeric priorities and stream
groups.  Either way, I'll go back to them with the results from the
discussions on this list.

As always, I appreciate the discussion and how honest and forthcoming
participants on this list are.

Thanks,

-- 
Chad Austin
http://chadaustin.me

Received on Tuesday, 4 November 2014 21:33:02 UTC