Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/loader/resource_scheduler.h" | 5 #include "content/browser/loader/resource_scheduler.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <utility> | 10 #include <utility> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/feature_list.h" | |
| 13 #include "base/macros.h" | 14 #include "base/macros.h" |
| 14 #include "base/metrics/field_trial.h" | 15 #include "base/metrics/field_trial.h" |
| 15 #include "base/metrics/histogram_macros.h" | 16 #include "base/metrics/histogram_macros.h" |
| 16 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 17 #include "base/supports_user_data.h" | 18 #include "base/supports_user_data.h" |
| 18 #include "content/common/resource_messages.h" | 19 #include "content/common/resource_messages.h" |
| 19 #include "content/public/browser/resource_controller.h" | 20 #include "content/public/browser/resource_controller.h" |
| 20 #include "content/public/browser/resource_request_info.h" | 21 #include "content/public/browser/resource_request_info.h" |
| 21 #include "content/public/browser/resource_throttle.h" | 22 #include "content/public/browser/resource_throttle.h" |
| 22 #include "net/base/host_port_pair.h" | 23 #include "net/base/host_port_pair.h" |
| 23 #include "net/base/load_flags.h" | 24 #include "net/base/load_flags.h" |
| 24 #include "net/base/request_priority.h" | 25 #include "net/base/request_priority.h" |
| 25 #include "net/http/http_server_properties.h" | 26 #include "net/http/http_server_properties.h" |
| 26 #include "net/url_request/url_request.h" | 27 #include "net/url_request/url_request.h" |
| 27 #include "net/url_request/url_request_context.h" | 28 #include "net/url_request/url_request_context.h" |
| 28 #include "url/scheme_host_port.h" | 29 #include "url/scheme_host_port.h" |
| 29 | 30 |
| 30 namespace content { | 31 namespace content { |
| 31 | 32 |
| 32 namespace { | 33 namespace { |
| 33 | 34 |
| 35 // When kPrioritySupportedRequestsDelayable is enabled, requests for | |
| 36 // H2/QUIC/SPDY resources can be delayed by the ResourceScheduler just as | |
| 37 // HTTP/1.1 resources are. Disabling this appears to have negative performance | |
| 38 // impact, see https://crbug.com/655585. | |
| 39 const base::Feature kPrioritySupportedRequestsDelayable{ | |
| 40 "PrioritySupportedRequestsDelayable", base::FEATURE_ENABLED_BY_DEFAULT}; | |
| 41 | |
| 34 enum StartMode { | 42 enum StartMode { |
| 35 START_SYNC, | 43 START_SYNC, |
| 36 START_ASYNC | 44 START_ASYNC |
| 37 }; | 45 }; |
| 38 | 46 |
| 39 // Flags identifying various attributes of the request that are used | 47 // Flags identifying various attributes of the request that are used |
| 40 // when making scheduling decisions. | 48 // when making scheduling decisions. |
| 41 using RequestAttributes = uint8_t; | 49 using RequestAttributes = uint8_t; |
| 42 const RequestAttributes kAttributeNone = 0x00; | 50 const RequestAttributes kAttributeNone = 0x00; |
| 43 const RequestAttributes kAttributeInFlight = 0x01; | 51 const RequestAttributes kAttributeInFlight = 0x01; |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 506 // attribute across redirects. | 514 // attribute across redirects. |
| 507 attributes |= kAttributeLayoutBlocking; | 515 attributes |= kAttributeLayoutBlocking; |
| 508 } else if (!has_html_body_ && | 516 } else if (!has_html_body_ && |
| 509 request->url_request()->priority() > | 517 request->url_request()->priority() > |
| 510 kLayoutBlockingPriorityThreshold) { | 518 kLayoutBlockingPriorityThreshold) { |
| 511 // Requests that are above the non_delayable threshold before the HTML | 519 // Requests that are above the non_delayable threshold before the HTML |
| 512 // body has been parsed are inferred to be layout-blocking. | 520 // body has been parsed are inferred to be layout-blocking. |
| 513 attributes |= kAttributeLayoutBlocking; | 521 attributes |= kAttributeLayoutBlocking; |
| 514 } else if (request->url_request()->priority() < | 522 } else if (request->url_request()->priority() < |
| 515 kDelayablePriorityThreshold) { | 523 kDelayablePriorityThreshold) { |
| 516 // Resources below the delayable priority threshold that are being | 524 if (base::FeatureList::IsEnabled(kPrioritySupportedRequestsDelayable)) { |
|
Randy Smith (Not in Mondays)
2016/10/19 16:41:43
I note that this lookup seems O(log n) (map) in th
jkarlin
2016/10/19 17:01:41
Done.
| |
| 517 // requested from a server that does not support native prioritization are | 525 // Resources below the delayable priority threshold that are considered |
| 518 // considered delayable. | 526 // delayable. |
| 519 url::SchemeHostPort scheme_host_port(request->url_request()->url()); | |
| 520 net::HttpServerProperties& http_server_properties = | |
| 521 *request->url_request()->context()->http_server_properties(); | |
| 522 if (!http_server_properties.SupportsRequestPriority(scheme_host_port)) | |
| 523 attributes |= kAttributeDelayable; | 527 attributes |= kAttributeDelayable; |
| 528 } else { | |
| 529 // Resources below the delayable priority threshold that are being | |
| 530 // requested from a server that does not support native prioritization | |
| 531 // are considered delayable. | |
| 532 url::SchemeHostPort scheme_host_port(request->url_request()->url()); | |
| 533 net::HttpServerProperties& http_server_properties = | |
| 534 *request->url_request()->context()->http_server_properties(); | |
| 535 if (!http_server_properties.SupportsRequestPriority(scheme_host_port)) | |
|
Randy Smith (Not in Mondays)
2016/10/19 16:41:43
I'll call out that another option (which probably
jkarlin
2016/10/19 17:01:41
Acknowledged.
| |
| 536 attributes |= kAttributeDelayable; | |
| 537 } | |
| 524 } | 538 } |
| 525 | 539 |
| 526 return attributes; | 540 return attributes; |
| 527 } | 541 } |
| 528 | 542 |
| 529 bool ShouldKeepSearching( | 543 bool ShouldKeepSearching( |
| 530 const net::HostPortPair& active_request_host) const { | 544 const net::HostPortPair& active_request_host) const { |
| 531 size_t same_host_count = 0; | 545 size_t same_host_count = 0; |
| 532 for (RequestSet::const_iterator it = in_flight_requests_.begin(); | 546 for (RequestSet::const_iterator it = in_flight_requests_.begin(); |
| 533 it != in_flight_requests_.end(); ++it) { | 547 it != in_flight_requests_.end(); ++it) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 588 // Syncronous requests could block the entire render, which could impact | 602 // Syncronous requests could block the entire render, which could impact |
| 589 // user-observable Clients. | 603 // user-observable Clients. |
| 590 if (!request->is_async()) | 604 if (!request->is_async()) |
| 591 return START_REQUEST; | 605 return START_REQUEST; |
| 592 | 606 |
| 593 // TODO(simonjam): This may end up causing disk contention. We should | 607 // TODO(simonjam): This may end up causing disk contention. We should |
| 594 // experiment with throttling if that happens. | 608 // experiment with throttling if that happens. |
| 595 if (!url_request.url().SchemeIsHTTPOrHTTPS()) | 609 if (!url_request.url().SchemeIsHTTPOrHTTPS()) |
| 596 return START_REQUEST; | 610 return START_REQUEST; |
| 597 | 611 |
| 598 if (using_spdy_proxy_ && url_request.url().SchemeIs(url::kHttpScheme)) | |
| 599 return START_REQUEST; | |
| 600 | |
| 601 net::HostPortPair host_port_pair = | 612 net::HostPortPair host_port_pair = |
| 602 net::HostPortPair::FromURL(url_request.url()); | 613 net::HostPortPair::FromURL(url_request.url()); |
| 603 url::SchemeHostPort scheme_host_port(url_request.url()); | |
| 604 net::HttpServerProperties& http_server_properties = | |
| 605 *url_request.context()->http_server_properties(); | |
| 606 | 614 |
| 607 // TODO(willchan): We should really improve this algorithm as described in | 615 if (!base::FeatureList::IsEnabled(kPrioritySupportedRequestsDelayable)) { |
| 608 // crbug.com/164101. Also, theoretically we should not count a | 616 if (using_spdy_proxy_ && url_request.url().SchemeIs(url::kHttpScheme)) |
| 609 // request-priority capable request against the delayable requests limit. | 617 return START_REQUEST; |
| 610 if (http_server_properties.SupportsRequestPriority(scheme_host_port)) | 618 |
| 611 return START_REQUEST; | 619 url::SchemeHostPort scheme_host_port(url_request.url()); |
| 620 | |
| 621 net::HttpServerProperties& http_server_properties = | |
| 622 *url_request.context()->http_server_properties(); | |
| 623 | |
| 624 // TODO(willchan): We should really improve this algorithm as described in | |
| 625 // crbug.com/164101. Also, theoretically we should not count a | |
| 626 // request-priority capable request against the delayable requests limit. | |
| 627 if (http_server_properties.SupportsRequestPriority(scheme_host_port)) | |
| 628 return START_REQUEST; | |
| 629 } | |
| 612 | 630 |
| 613 // Non-delayable requests. | 631 // Non-delayable requests. |
| 614 if (!RequestAttributesAreSet(request->attributes(), kAttributeDelayable)) | 632 if (!RequestAttributesAreSet(request->attributes(), kAttributeDelayable)) |
| 615 return START_REQUEST; | 633 return START_REQUEST; |
| 616 | 634 |
| 617 if (in_flight_delayable_count_ >= kMaxNumDelayableRequestsPerClient) | 635 if (in_flight_delayable_count_ >= kMaxNumDelayableRequestsPerClient) |
| 618 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; | 636 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; |
| 619 | 637 |
| 620 if (ShouldKeepSearching(host_port_pair)) { | 638 if (ShouldKeepSearching(host_port_pair)) { |
| 621 // There may be other requests for other hosts that may be allowed, | 639 // There may be other requests for other hosts that may be allowed, |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 889 client->ReprioritizeRequest(scheduled_resource_request, old_priority_params, | 907 client->ReprioritizeRequest(scheduled_resource_request, old_priority_params, |
| 890 new_priority_params); | 908 new_priority_params); |
| 891 } | 909 } |
| 892 | 910 |
| 893 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( | 911 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( |
| 894 int child_id, int route_id) { | 912 int child_id, int route_id) { |
| 895 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; | 913 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; |
| 896 } | 914 } |
| 897 | 915 |
| 898 } // namespace content | 916 } // namespace content |
| OLD | NEW |