Subject: Design Issue: PUSH_PROMISE and Stream Priority

From: James M Snell <[email-masked]>
Date: Thu, 25 Apr 2013 11:03:08 -0700

https://github.com/http2/http2-spec/issues/75

The current draft (-02) says, "The endpoint establishing a new stream
can assign a priority for the stream."

However, the spec does not define how a stream established using
PUSH_PROMISE can assign the priority for a stream, nor does the spec
discuss whether the notion of stream priority applies to push streams.

The spec currently states that PUSH_PROMISE is followed later on by a
HEADERS frame.

If priority applies to push streams, then we need to add that priority
can be assigned by allowing the use of a HEADERS+PRIORITY frame.
Otherwise, we need to clarify the spec text to say that push streams
have no priority.

---

From: Martin Thomson <[email-masked]>
Date: Thu, 25 Apr 2013 16:48:41 -0700

Good point.  The hope was that a reprioritization frame would be
proposed (Will, Roberto, we're all still waiting).

If that's enough, then adding a default (maybe 2^30) would fix this.

---

From: James M Snell <[email-masked]>
Date: Thu, 25 Apr 2013 17:03:47 -0700

A new frame is not required. We already have HEADERS+PRIORITY and
HEADERS. The PUSH_PROMISE definition states that the promise will be
followed up by a HEADERS frame, then data frames. If we allow it to be
HEADERS or HEADERS+PRIORITY then we meet the requirement.

That said, is there even a need for server pushed streams to specify a
priority? Do we want to allow servers to dictate priority to the
client? I can see a number of ways in which a naughty server could
abuse that privilege.

Another question: do pushed streams inherit the same priority as their
associated "parent" streams? That is, client initiates a stream #1 to
the server with priority 5, server responds on that stream with two
PUSH_PROMISES for server-initiated streams #2 and #4... do streams #2
and #4 inherit the same priority as stream #1. (Please say no, Please
say no)

- James

---

From: Martin Thomson <[email-masked]>
Date: Thu, 25 Apr 2013 17:17:03 -0700

> client? I can see a number of ways in which a naughty server could

Having the server tell you priority is fairly pointless.  The client
would need something.  Apparently, the new frame was considered better
than having an otherwise empty HEADERS+PRIORITY.

> and #4 inherit the same priority as stream #1. (Please say no, Please

I'm going to say yes and then make your day even worse by pointing out
that RST_STREAM(CANCEL) on stream #1 is expected to terminate all
related push streams, even if stream #1 is long gone.  (I'm assuming
that one didn't sink in when you read it.)  At least with priority you
can copy that state over when you copy over request headers (unless
you want reprioritization of the "parent" to also reprioritize pushes,
which seems mega-crazy to me).  The push cancellation thing is messy.

---

From: Roberto Peon <[email-masked]>
Date: Thu, 25 Apr 2013 19:36:03 -0700

I am traveling but should be back by Monday. I'll be slow before then as
I'm having to type in the phone.

---

From: William Chan (陈智昌) <[email-masked]>
Date: Thu, 25 Apr 2013 22:29:07 -0700

We have not proposed a reprioritization frame since there was some mild
resistance before at the Tokyo interim meeting, although most of that
concern was about the larger prioritization proposal and not strictly
reprioritization. We promised to go get data and come back and report. We
have not gotten said data yet (it's in progress), so I don't have much to
report (no data, only status if people are interested. I'm inclined to wait
until I have data). If reprioritization is not controversial, then we can
go ahead and propose a frame for that and revisit the rest of the larger
prioritization proposal when we have data.

As far as the priority being useless to send with push streams, the only
reason I can see that as being useful is perhaps saving a reprioritization
frame (meh) or if you have a "smart" server that's doing some learning
process to decide how to prioritize push streams in absence of client
information, then perhaps this would allow for informing the client as
you're learning. That's a weak argument too because you can just log that
information server side to evaluate your learning process.

Actually, if we don't strictly assume HTTP style client initiated
request/response application protocol semantics, then at the framing layer
with fully bidirectional streams, the server may be requesting that the
client send data back to the server according to the server advisory
priority. That is, since streams are bidirectional, you can imagine servers
initiating a request/response pair.

Now, as to the push stream priority default, in general for a web browsing
case, the "parent" stream will be the root document of a page load, and the
push streams will be subresources, which should generally be lower priority
than the root document. So I don't think priority inheritance is advisable
for this scenario, and at least for the HTTP case, it's not really
important since it's a server-side implementation detail - in absence of
client advisory priorities, the server just sends streams in whatever order
it wants. No need to spec a required default or anything, let server
implementations innovate here. A reprioritization frame would enable the
client to send advisory priorities here to better inform the server. And I
would recommend we allow clients to do so.

---

From: James M Snell <[email-masked]>
Date: Fri, 26 Apr 2013 00:12:38 -0700

My apologies,  i accidentally excluded the list in this reply.
On Apr 26, 2013 12:11 AM, "James M Snell" <[email-masked]> wrote:

>
> On Apr 25, 2013 10:29 PM, "William Chan (陈智昌)" <[email-masked]>
> wrote:
> >
> Waiting for the data is fine. I'm not opposed to a prioritization frame
> but I worry about creating too many special purpose frame types at too fine
> gained a level. We'll need to be careful.
>
> This hits the core of the problem.. Are we creating a general purpose
> bidirectional framing protocol that we can layer http onto or are we
> creating a new http based on frames.  If the former, then push stream
> priority may make sense.  If the latter, it could be dangerous and
> completely unnecessary.
>
> For now, let's just say that only client initiated streams have a
> priority. Doing so eliminates many potentially messy issues.  If someone
> wants to experiment with prioritized push streams later on down the road ,
> they can do so.
>
> - James
>
> > Now, as to the push stream priority default, in general for a web
> browsing case, the "parent" stream will be the root document of a page
> load, and the push streams will be subresources, which should generally be
> lower priority than the root document. So I don't think priority
> inheritance is advisable for this scenario, and at least for the HTTP case,
> it's not really important since it's a server-side implementation detail -
> in absence of client advisory priorities, the server just sends streams in
> whatever order it wants. No need to spec a required default or anything,
> let server implementations innovate here. A reprioritization frame would
> enable the client to send advisory priorities here to better inform the
> server. And I would recommend we allow clients to do so.
> >
> >
> >
> >
> >> I am traveling but should be back by Monday. I'll be slow before then
> as I'm having to type in the phone.
> >>

---

From: RUELLAN Herve <[email-masked]>
Date: Fri, 26 Apr 2013 09:32:24 +0000

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] On Behalf Of
> William Chan (???)
> Sent: vendredi 26 avril 2013 07:29
> To: Roberto Peon
> Cc: Martin Thomson; James Snell; HTTP Working Group
> Subject: Re: Design Issue: PUSH_PROMISE and Stream Priority
> 
> have not gotten said data yet (it's in progress), so I don't have much to report
> (no data, only status if people are interested. I'm inclined to wait until I have
> data). If reprioritization is not controversial, then we can go ahead and
> propose a frame for that and revisit the rest of the larger prioritization
> proposal when we have data.
> 
> reason I can see that as being useful is perhaps saving a reprioritization frame
> (meh) or if you have a "smart" server that's doing some learning process to
> decide how to prioritize push streams in absence of client information, then
> perhaps this would allow for informing the client as you're learning. That's a
> weak argument too because you can just log that information server side to
> evaluate your learning process.
> 
> with fully bidirectional streams, the server may be requesting that the client
> send data back to the server according to the server advisory priority. That is,
> since streams are bidirectional, you can imagine servers initiating a
> request/response pair.
> 
> than the root document. So I don't think priority inheritance is advisable for
> this scenario, and at least for the HTTP case, it's not really important since it's
> a server-side implementation detail - in absence of client advisory priorities,
> the server just sends streams in whatever order it wants. No need to spec a
> required default or anything, let server implementations innovate here. A
> reprioritization frame would enable the client to send advisory priorities here
> to better inform the server. And I would recommend we allow clients to do
> so.

My reading of this is that a server could set a priority on a pushed stream as an information for the client: the priority value is the priority selected by the server for the stream. Then, if the client is not happy with this server defined priority it could use a reprioritization frame to change the priority of the stream.

Hervé.

---

From: RUELLAN Herve <[email-masked]>
Date: Fri, 26 Apr 2013 10:43:39 +0000

> From: Martin Thomson [mailto:[email-masked]]
> Sent: vendredi 26 avril 2013 02:17
> To: James M Snell
> Cc: [email-masked]
[snip]
> I'm going to say yes and then make your day even worse by pointing out that
> RST_STREAM(CANCEL) on stream #1 is expected to terminate all related
> push streams, even if stream #1 is long gone.  (I'm assuming that one didn't
> sink in when you read it.)  At least with priority you can copy that state over
> when you copy over request headers (unless you want reprioritization of the
> "parent" to also reprioritize pushes, which seems mega-crazy to me).  The
> push cancellation thing is messy.

I'm seeing the problem in a slightly different way: in the current usage of SPDY, the client initiates the stream #1 by sending the HEADERS+PRIORITY frame with the FINAL flag set to half close it. Therefore, the client is unable to send a RST_STREAM on stream #1 to terminate the related push streams.
To take into account server push, the client will want to keep the stream #1 fully open until at least it is half closed by the server. This means that in HTTP/2.0, stream #1 will stay alive much longer.

Hervé.

---

From: Patrick McManus <[email-masked]>
Date: Fri, 26 Apr 2013 08:20:59 -0700

On Thu, Apr 25, 2013 at 10:29 PM, William Chan (陈智昌)
<[email-masked]>wrote:

>  A reprioritization frame would enable the client to send advisory
> priorities here to better inform the server. And I would recommend we allow
> clients to do so.
>
>
+1. For the stage we are at now, let's just do that.

---

From: James M Snell <[email-masked]>
Date: Fri, 26 Apr 2013 09:27:27 -0700

Ok, there are a couple of issues that have been discussed in this
thread.. let me see if I can summarize the priority issue: The spec
currently states that all Streams can have a priority, but provides no
way for the Server to specify the priority of PUSH_PROMISE streams.
For this there are several possible solutions:

    A. We can simply say PUSH_PROMISE streams have no priority.
    B. We can say that PUSH_PROMISE streams inherit the priority of
their parent, client-initiated stream
    C. We can allow the server to use HEADERS+PRIORITY or a new
Reprioritization Frame to establish the priority of a pushed stream.

For Options B and C, there is an open question about whether and how
an http client would even make use of stream priority.

My recommendation at this point is to go with option A. If, at some
point down the road, someone wants to start experimenting with
prioritized push streams, then more power to them. For now, I just
don't see the justification for it.

- James

---

From: Martin Thomson <[email-masked]>
Date: Fri, 26 Apr 2013 11:35:21 -0700

> Reprioritization Frame to establish the priority of a pushed stream.

That seems like a fair taxonomy.

A is not possible.  There is no such thing as no priority.  Default
priority, perhaps.  At the point that you have to contend with
choosing between two streams, then you have prioritization.

---

From: Roberto Peon <[email-masked]>
Date: Fri, 26 Apr 2013 11:46:44 -0700

Sorry I'm so slow-- internet connectivity is absolutely crud where I am
right now.

What will the client do with the information a push_promise?
 The headers, etc. are obvious--
That data will prevent the client from creating another (redundant) request
for the resource/
If the client is given priority information with a push_promose, perhaps
this might cause the client to send a reprio message immediately to
whatever the client wants, potentially before the server begins sending
bytes or creates the stream/reads the bytes. This assumes that the server
even *knows* what the priority is at that point, which it may not.

... and, really, that is the only thing I can see the client doing with
that information. Does anyone see anything else it might do with it?

does anyone think this is likely to be useful?

---

From: James M Snell <[email-masked]>
Date: Sat, 27 Apr 2013 13:30:34 -0700

I honestly cannot imagine any scenario where it would be useful or
desirable to allow the server to set a priority for pushed streams. My
preference would be for us to say that only client-initiated streams
have a priority. If we want to leave the door open later on, we can
say that priority on server-initiated streams is undefined and out of
scope rather than saying it's not allowed at all.

On Fri, Apr 26, 2013 at 11:46 AM, Roberto Peon <[email-masked]> wrote:
> this might cause the client to send a reprio message immediately to whatever
> the client wants, potentially before the server begins sending bytes or
> creates the stream/reads the bytes. This assumes that the server even
> *knows* what the priority is at that point, which it may not.
>
> ... and, really, that is the only thing I can see the client doing with that
> information. Does anyone see anything else it might do with it?
>
> On Fri, Apr 26, 2013 at 11:35 AM, Martin Thomson <[email-masked]>
> wrote:
>>

---

From: Roberto Peon <[email-masked]>
Date: Sat, 27 Apr 2013 14:27:56 -0700

Sending of a message including a priority field != setting a priority.

Server pushed streams have priority, but they are most likely to be set by
the client.
I was understanding that we were asking a separate question: If it was
worthwhile to have the server announce what priority it decided to use for
a pushed stream, and if so... when (e.g. at PUSH_PROMISE time, or, when
doing HEADERS).

-=R

On Sat, Apr 27, 2013 at 1:30 PM, James M Snell <[email-masked]> wrote:

> whatever
> that

---

From: James M Snell <[email-masked]>
Date: Sat, 27 Apr 2013 14:34:14 -0700

I believe we're saying the same thing in different ways. Given the
language *currently* in the spec, the initiator of a stream can
specify a priority value for that stream and the recipient of the
stream needs to try to process those streams accordingly. What I'm
saying is that there is absolutely no value in allowing the server to
specify a value for the priority on a stream.

On Sat, Apr 27, 2013 at 2:27 PM, Roberto Peon <[email-masked]> wrote:
> worthwhile to have the server announce what priority it decided to use for a
> pushed stream, and if so... when (e.g. at PUSH_PROMISE time, or, when doing
> HEADERS).
>
> -=R
>
>

---

From: Roberto Peon <[email-masked]>
Date: Sat, 27 Apr 2013 14:43:03 -0700

There is a value, but I don't know if it is worth the 4 bytes. :)
(The value is that now the client knows what the priority is, and has a
better idea of when to change it if it is too far off from what it should
be.)
--=R

---

From: James M Snell <[email-masked]>
Date: Sat, 27 Apr 2013 23:20:40 -0700

Then let's just say that,  currently, setting and using the priority on
push streams is out of scope. If we later determine that it is something
worth doing, we can make it in scope.