cURL / Mailing Lists / curl-library / Single Mail


Re: HTTP/2 Stream Priority and Dependency

From: Tatsuhiro Tsujikawa <>
Date: Sat, 06 Jun 2015 06:54:47 +0000


On Sat, Jun 6, 2015 at 1:35 AM Lucas Pardue <> wrote:

> Hi,
> > I could imagine that as long the application hasn't yet removed the
> handle
> > from the multi handle, it could theoretically still be used for this
> even post-
> > completion of its request. I just feel like a use case I'm not eager to
> work on
> > and I think I'd rather document as unsupported for now. Then someone who
> > feels strongly for this can still work on adding it later. Possibly
> myself of
> > course, just later on.
> Sounds like a good plan. Thinking about the server side, how likely is it
> that they want to hold or process information related to a closed stream?
> My guess is that it is low. The spec 5.3.4 says " If it has retained enough
> state to do so, an endpoint receiving a PRIORITY frame that changes the
> priority of a closed stream SHOULD alter the dependencies of the streams
> that depend on it."
nghttp2 will retain certain amount of closed stream (active + closed <= max
concurrent streams). But it is not strict requirement by the RFC 7540, I'm
not really sure other implementations do the same.
HTTP/2 priority handling itself is not popular now, most implementations
listed in HTTP/2 implementations list lack of it.

> > I wonder how we should best pass in the "exclusive flag" for a stream.
> One
> > way I can think of is to offer a separate exclusive dep option called
> > CURLOPT_STREAM_DEPENDS_EXLUSIVE or something. It would set both the
> > "Stream Dependency" and the "E" fields and the other option would clear
> > the "E" field.
> Can you unset an exclusive dependency? I hadn't thought about that before
> but it seems totally possible. The dependency tree would need to be
> reshuffled but that happens in other cases too.
I think unsetting exclusive dependency is just issue another dependency
request without exclusive flag. That's how HTTP/2 dependency tree works.

> > The client is in full control of what stream dependencies it sets so
> there
> > should be no surprises, right? I don't see how a callback or similar is
> needed
> > for this. Or did you have something special in mind?
> The dependency tree can get reshuffled for a number of reasons. I think it
> would be easy for a client to lose track of the tree state, unless they
> hold some model in application code (which might be the best thing to do if
> they care about it!). However, it is really up to the end point to manage
> the dependency tree information in order to provision the resources. The
> client just needs to send valid frames that hopefully make logical sense
> for its purpose.
> Section 5.3.4 talks about streams being removed from the dependency tree
> but I'm not sure how that is done. It then touches on redistribution of
> weights, which sounds a bit complicated.
> With all the complex edge cases I wonder if the approach to this API
> should be a "best-effort" one.
Priority is "best-effort" and optional in HTTP/2. It is fully up to the
server how it understand or react to the priority request from client. I
think client like web browser will just use rather static priority tree
(just like you mentioned in the below as used in Firefox), and it does not
require complex manipulation of stream weight in client side. Those
complex calculations are done mostly in server side.
Since libcurl uses nghttp2, it takes into account priority when uploading
contents; stream which has higher weight is likely to finish earlier.
Perhaps, libcurl just performs what application does, and leave the
dependency tree state to the application.

> Have you considered that PRIORITY frames can be sent on idle streams? This
> allows for the behaviour of dependency groups, described in Patrick
> McManus' blog post
> . I'm not sure if this is already covered by your API suggestion but in
> essence we would want to be able to send a frame without a real request (no
In nghttp2 API wise, this is possible, just use nghttp2_submit_priority()
with idle stream ID, and use nghttp2_session_set_next_stream_id() to
specify the starting stream ID for actual request. The thing is libcurl
API hides stream ID as of now, so we may have to create handle for this
idle stream for this purpose. Introducing stream ID makes easier in api
(and code) wise, but it is too specific HTTP/2.

Best regards,
Tatsuhiro Tsuijkawa

> Regards
> Lucas
> -------------------------------------------------------------------
> List admin:
> Etiquette:

List admin:
Received on 2015-06-06