Subject: PUSH_PROMISE and load balancers

From: Stuart Douglas <[email-masked]>
Date: Fri, 26 Sep 2014 10:33:38 +1000

So I have been thinking about the case where you have a HTTP2 aware load 
balancer that serves both HTTP1 and HTTP2 clients, and uses HTTP2 to 
connect to the backend servers.

Such load balancers will generally maintain a connection pool to the 
backend servers, and to allow PUSH_PROMISE to be used will need to 
enable push on the connection.

I am thinking about then case when a HTTP1 client connects to this 
proxy, the backend servers will attempt to use PUSH_PROMISE to push 
content to the server, even though the load balancer knows in advance 
that it cannot accept the content.

It would be possible to hack around this to some extent (e.g. using a 
custom header to signify that push should be disabled for this request), 
however I was thinking that a much nicer solution would be to add a flag 
to the HEADERS frame indicating that push should be disabled for this 
request only (i.e. no PUSH_PROMISE frame should be sent with this 
request as the associated stream id).

Note that you can't really just send a SETTINGS frame before each 
request to alter the SETTINGS_ENABLE_PUSH flag. This will work for the 
simple case if you are allocating one connection per request, however it 
won't work if the proxy is multiplexing requests from different clients 
over the same HTTP2 connection.

Thoughts?

Stuart

---

From: Martin Thomson <[email-masked]>
Date: Fri, 26 Sep 2014 07:54:51 +0100

The easiest solution is to use two connections: one for push-enabled
clients, and one for those without push support (including HTTP/1.1
clients as well as clients that disable push).

The SETTINGS_ENABLE_PUSH flag can be different on each connection.

On 26 September 2014 01:33, Stuart Douglas <[email-masked]> wrote:
> balancer that serves both HTTP1 and HTTP2 clients, and uses HTTP2 to connect
> to the backend servers.
>
> Such load balancers will generally maintain a connection pool to the backend
> servers, and to allow PUSH_PROMISE to be used will need to enable push on
> the connection.
>
> I am thinking about then case when a HTTP1 client connects to this proxy,
> the backend servers will attempt to use PUSH_PROMISE to push content to the
> server, even though the load balancer knows in advance that it cannot accept
> the content.
>
> It would be possible to hack around this to some extent (e.g. using a custom
> header to signify that push should be disabled for this request), however I
> was thinking that a much nicer solution would be to add a flag to the
> HEADERS frame indicating that push should be disabled for this request only
> (i.e. no PUSH_PROMISE frame should be sent with this request as the
> associated stream id).
>
> Note that you can't really just send a SETTINGS frame before each request to
> alter the SETTINGS_ENABLE_PUSH flag. This will work for the simple case if
> you are allocating one connection per request, however it won't work if the
> proxy is multiplexing requests from different clients over the same HTTP2
> connection.
>
> Thoughts?
>
> Stuart
>
>

---

From: Stuart Douglas <[email-masked]>
Date: Fri, 26 Sep 2014 17:21:02 +1000

I know there are ways to work around it, but it seems sub-optimal to 
need to maintain two separate connection pools for push enabled vs 
non-push enabled clients, especially when it seems to be easy to fix on 
a protocol level.

I was also thinking that is might be possible to address this as an 
extension, you could send a frame to disable push before sending the 
headers frame, but with compression a custom header will probably 
actually turn out to be less data per request anyway.

Stuart

Martin Thomson wrote:
> On 26 September 2014 01:33, Stuart Douglas<[email-masked]>  wrote:

---

From: Martin Thomson <[email-masked]>
Date: Fri, 26 Sep 2014 08:32:12 +0100

On 26 September 2014 08:21, Stuart Douglas <[email-masked]> wrote:
> I know there are ways to work around it, but it seems sub-optimal to need to
> maintain two separate connection pools for push enabled vs non-push enabled
> clients, especially when it seems to be easy to fix on a protocol level.

It's still strictly better than HTTP/1.1.

---

From: Daniel Sommermann <[email-masked]>
Date: Fri, 26 Sep 2014 09:23:54 -0700

> It's still strictly better than HTTP/1.1.

I don't know about *strictly* better. Two connection pools is an 
increase in complexity in the LB and could lead to worse performance. 
You might have to pay a penalty of opening a new connection to a server 
even though you have a connection ready, whereas in HTTP/1 you didn't 
have to open another connection. Are we really so pressed for bits in 
the flags that we can't move this there? Maybe SETTINGS is not the right 
place for enabling/disabling server push.

Daniel

---

From: Glen Knowles <[email-masked]>
Date: Fri, 26 Sep 2014 14:25:03 -0700

On Fri, Sep 26, 2014 at 9:23 AM, Daniel Sommermann <[email-masked]> wrote:

> Maybe SETTINGS is not the right place for enabling/disabling server push.
>

My first thought was that what is going to be pushed is decided by the
content of the request, and that therefore a request header would be the
best way to communicate such preferences up to the application layer on the
origin that's choosing what to push. Putting in settings on the transport
seems wrong.

---

From: MISSY LAWSON <[email-masked]>
Date: Tue, 30 Sep 2014 17:05:18 -0500

Sent from my iPhone

> On Sep 26, 2014, at 4:25 PM, Glen Knowles <[email-masked]> wrote:
> 
> My first thought was that what is going to be pushed is decided by the content of the request, and that therefore a request header would be the best way to communicate such preferences up to the application layer on the origin that's choosing what to push. Putting in settings on the transport seems wrong.
>