Update priorities of pushed streams |
|||||
Issue descriptionOver-eager servers can make poor use of HTTP/2 push: they might push low-priority resources interleaved with high-priority resources, or worse, they might push resources that are not needed at all. I propose guarding against such servers by updating priorities of push streams. Specifically: 1. On receiving a push promise for a resource that is not cached ( crbug.com/232040 ), the pushed stream will be assigned an IDLE priority. Chrome will communicate this to the server using an appropriate PRIORITY frame. 2. When a pushed stream is matched to a request, if the stream is still open, then the pushed stream's priority will be updated to match the request's priority. Chrome will communicate this update using appropriate PRIORITY frames (one to reassign old children of the pushed stream, and another to move the pushed stream). The basic idea is to split pushed streams into "speculative" and "desired" groups. A pushed stream starts as speculative, then becomes desired once it matches an actual request. Speculative streams have IDLE priority to discourage the server from scheduling them unless there are no other outstanding requests. I pitched this idea (offline) to rdsmith and bnc, who agreed this idea sounds good. Note also that Firefox does something similar (to my knowledge), where pushed streams initially have "speculative" priority (defined here: http://bitsup.blogspot.com/2015/01/http2-dependency-priorities-in-firefox.html) but are upgraded once they match an actual request. The implementation of parts 1 and 2 is roughly: 1. In OnPushPromise, we pass ConvertRequestPriorityToSpdyPriority(IDLE) to TryCreatePushedStream. Then, if the stream is created, TryCreatePushStream will update SpdySession::priority_dependency_state_ and send a PRIORITY update, similar to Http2PriorityDependencies::OnStreamSynSent. 2. In SpdySession::GetPushStream, if a matching pushed stream is found and the stream is still open, the stream's priority is updated and PRIORITY frames are sent. This can be protected behind finch if desired, although given the relatively low usage of push in the wild, I doubt we'd get much meaningful performance data from a finch experiment. I do plan to run a few manual experiments. This idea should apply to QUIC as well, although I'm less familiar with that code.
,
Nov 23 2016
,
Jan 11 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/5d22c18a5718b6e80507a90dae35a6e0ee5a6333 commit 5d22c18a5718b6e80507a90dae35a6e0ee5a6333 Author: tombergan <tombergan@chromium.org> Date: Wed Jan 11 02:05:35 2017 http2: Update priorities of pushed streams On receiving a PUSH_PROMISED, the pushed stream is assigned an IDLE priority because it is "speculative". When the pushed stream matches an actual request, the stream's priority is updated to match that of the request. In addition to unit tests, I tested this against a local HTTP/2 server that served the following page: <html><body> <script type="application/javascript" src="/a.js"></script> <script type="application/javascript" src="/b.js"></script> <script type="application/javascript" src="/c.js"></script> </body></html> The server was configured to push "/b.js" when serving the HTML. I verified that the server's priority tree went through the following sequence: 1. {html -> b.js}, after receiving the PUSH_PROMISE 2. {html -> a.js -> b.js}, after the preload scanner finds a.js 3. {html -> a.js -> b.js}, after the preload scanner finds b.js 4. {html -> a.js -> b.js -> c.js}, after the preload scanner finds c.js Before this change, the final priority tree would have been: {html -> {b.js, {a.js -> c.js}}} BUG=668298 R=rdsmith@chromium.org,bnc@chromium.org Review-Url: https://codereview.chromium.org/2596703002 Cr-Commit-Position: refs/heads/master@{#442770} [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/http/http_network_transaction_unittest.cc [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/log/net_log_event_type_list.h [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/buffered_spdy_framer.cc [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/buffered_spdy_framer.h [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/http2_priority_dependencies.cc [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/http2_priority_dependencies.h [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/http2_priority_dependencies_unittest.cc [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/spdy_http_stream.cc [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/spdy_network_transaction_unittest.cc [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/spdy_session.cc [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/spdy_session.h [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/spdy_session_unittest.cc [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/spdy_stream.cc [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/spdy_stream.h [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/spdy_stream_unittest.cc [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/spdy_test_util_common.cc [modify] https://crrev.com/5d22c18a5718b6e80507a90dae35a6e0ee5a6333/net/spdy/spdy_test_util_common.h
,
Jan 11 2017
This is done for HTTP/2. +ckrasic Buck, I believe QUIC is still using integer priorities ... would a similar change as above make sense for QUIC?
,
Feb 16 2018
,
Aug 3
This bug has an owner, thus, it's been triaged. Changing status to "assigned". |
|||||
►
Sign in to add a comment |
|||||
Comment 1 by tombergan@chromium.org
, Nov 23 2016