Index: content/browser/loader/resource_scheduler.cc |
diff --git a/content/browser/loader/resource_scheduler.cc b/content/browser/loader/resource_scheduler.cc |
index 1d118f0ffbc2ae3be243e75f8eb227a1073edfcf..e538154f6aa4af671db630dc6897e99fcd608c99 100644 |
--- a/content/browser/loader/resource_scheduler.cc |
+++ b/content/browser/loader/resource_scheduler.cc |
@@ -4,8 +4,6 @@ |
#include <set> |
-#include "content/browser/loader/resource_scheduler.h" |
- |
#include "base/metrics/field_trial.h" |
#include "base/metrics/histogram.h" |
#include "base/stl_util.h" |
@@ -14,6 +12,7 @@ |
#include "base/time/time.h" |
#include "content/common/resource_messages.h" |
#include "content/browser/loader/resource_message_delegate.h" |
+#include "content/browser/loader/resource_scheduler.h" |
mmenke
2015/08/07 16:55:10
This should actually go at the top, before the <se
Pat Meenan
2015/08/07 20:48:10
Done.
|
#include "content/public/browser/resource_controller.h" |
#include "content/public/browser/resource_request_info.h" |
#include "content/public/browser/resource_throttle.h" |
@@ -37,6 +36,8 @@ const char kThrottleCoalesceFieldTrialCoalesce[] = "Coalesce"; |
const char kRequestLimitFieldTrial[] = "OutstandingRequestLimiting"; |
const char kRequestLimitFieldTrialGroupPrefix[] = "Limit"; |
+const char kResourcePrioritiesFieldTrial[] = "ResourcePriorities"; |
+ |
// Post ResourceScheduler histograms of the following forms: |
// If |histogram_suffix| is NULL or the empty string: |
// ResourceScheduler.base_name.histogram_name |
@@ -77,6 +78,8 @@ static const size_t kCoalescedTimerPeriod = 5000; |
static const size_t kMaxNumDelayableRequestsPerClient = 10; |
static const size_t kMaxNumDelayableRequestsPerHost = 6; |
static const size_t kMaxNumThrottledRequestsPerClient = 1; |
mmenke
2015/08/07 16:55:10
+Default
Pat Meenan
2015/08/07 20:48:10
Done.
|
+static const size_t kMaxNumDelayableWhileLayoutBlocking = 1; |
mmenke
2015/08/07 16:55:11
+Default
Pat Meenan
2015/08/07 20:48:09
Done.
|
+static const net::RequestPriority kLayoutBlockingPriorityThreshold = net::LOW; |
mmenke
2015/08/07 16:55:11
+Default
Pat Meenan
2015/08/07 20:48:10
Done.
|
struct ResourceScheduler::RequestPriorityParams { |
RequestPriorityParams() |
@@ -314,7 +317,46 @@ class ResourceScheduler::Client { |
scheduler_(scheduler), |
in_flight_delayable_count_(0), |
total_layout_blocking_count_(0), |
- throttle_state_(ResourceScheduler::THROTTLED) {} |
+ throttle_state_(ResourceScheduler::THROTTLED), |
+ max_num_delayable_requests_(kMaxNumDelayableRequestsPerClient), |
+ max_num_delayable_while_layout_blocking_( |
+ kMaxNumDelayableWhileLayoutBlocking), |
+ enable_layout_blocking_threshold_(false), |
+ in_flight_layout_blocking_threshold_(0), |
+ layout_blocking_priority_threshold_(kLayoutBlockingPriorityThreshold) { |
+ // The field trial parameters are also encoded into the group name since |
+ // the variations component is not available from here and plumbing the |
+ // options through the code is overkill for a short experiment. |
+ // |
+ // The group name encoding looks like this: |
+ // <descriptiveName>_ABCDE_E2_F_G |
+ // A - fetchDeferLateScripts (1 for true, 0 for false) |
+ // B - fetchIncreaseFontPriority (1 for true, 0 for false) |
+ // C - fetchIncreaseAsyncScriptPriority (1 for true, 0 for false) |
+ // D - fetchIncreasePriorities (1 for true, 0 for false) |
+ // E - fetchEnableLayoutBlockingThreshold (1 for true, 0 for false) |
+ // E2 - fetchLayoutBlockingThreshold (Numeric) |
+ // F - fetchMaxNumDelayableWhileLayoutBlocking (Numeric) |
+ // G - fetchMaxNumDelayableRequests (Numeric) |
+ std::string resource_priorities_trial_group = |
+ base::FieldTrialList::FindFullName(kResourcePrioritiesFieldTrial); |
+ std::vector<std::string> split_group( |
+ base::SplitString(resource_priorities_trial_group, "_", |
+ base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL)); |
+ if (split_group.size() == 5 && split_group[1].length() == 5) { |
+ // fetchIncreasePriorities |
+ if (split_group[1].at(3) == '1') |
+ layout_blocking_priority_threshold_ = net::MEDIUM; |
+ enable_layout_blocking_threshold_ = split_group[1].at(4) == '1'; |
+ size_t numeric_value = 0; |
+ if (base::StringToSizeT(split_group[2], &numeric_value)) |
+ in_flight_layout_blocking_threshold_ = numeric_value; |
+ if (base::StringToSizeT(split_group[3], &numeric_value)) |
+ max_num_delayable_while_layout_blocking_ = numeric_value; |
+ if (base::StringToSizeT(split_group[4], &numeric_value)) |
+ max_num_delayable_requests_ = numeric_value; |
+ } |
mmenke
2015/08/07 16:55:11
Why are these per-client variables, and not in the
Pat Meenan
2015/08/07 20:48:10
Moved to the scheduler itself and pass into each c
|
+ } |
~Client() { |
// Update to default state and pause to ensure the scheduler has a |
@@ -625,22 +667,20 @@ class ResourceScheduler::Client { |
// If a request is already marked as layout-blocking make sure to keep the |
// classification across redirects unless the priority was lowered. |
if (request->classification() == LAYOUT_BLOCKING_REQUEST && |
- request->url_request()->priority() > net::LOW) { |
+ request->url_request()->priority() > |
+ layout_blocking_priority_threshold_) { |
return LAYOUT_BLOCKING_REQUEST; |
} |
- if (!has_body_ && request->url_request()->priority() > net::LOW) |
+ if (!has_body_ && |
+ request->url_request()->priority() > |
+ layout_blocking_priority_threshold_) |
return LAYOUT_BLOCKING_REQUEST; |
mmenke
2015/08/07 16:55:11
Add braces
mmenke
2015/08/07 16:55:11
Perhaps we should rename this? Either a request b
Pat Meenan
2015/08/07 20:48:09
There are effectively 3 levels of groupings that w
Pat Meenan
2015/08/07 20:48:09
Done.
|
- if (request->url_request()->priority() < net::LOW) { |
- net::HostPortPair host_port_pair = |
Bryan McQuade
2015/08/07 18:02:26
why did the hostportpair logic get removed?
Pat Meenan
2015/08/07 20:48:09
It was doing more harm than good. If the resource
|
- net::HostPortPair::FromURL(request->url_request()->url()); |
- net::HttpServerProperties& http_server_properties = |
- *request->url_request()->context()->http_server_properties(); |
- if (!http_server_properties.SupportsRequestPriority(host_port_pair) && |
- ContainsKey(in_flight_requests_, request)) { |
- return IN_FLIGHT_DELAYABLE_REQUEST; |
- } |
+ if (request->url_request()->priority() < |
+ layout_blocking_priority_threshold_ && |
+ ContainsKey(in_flight_requests_, request)) { |
+ return IN_FLIGHT_DELAYABLE_REQUEST; |
} |
return NORMAL_REQUEST; |
} |
@@ -769,11 +809,11 @@ class ResourceScheduler::Client { |
} |
// High-priority and layout-blocking requests. |
- if (url_request.priority() >= net::LOW) { |
+ if (url_request.priority() >= layout_blocking_priority_threshold_) { |
return START_REQUEST; |
} |
- if (in_flight_delayable_count_ >= kMaxNumDelayableRequestsPerClient) { |
+ if (in_flight_delayable_count_ >= max_num_delayable_requests_) { |
return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; |
} |
@@ -783,15 +823,36 @@ class ResourceScheduler::Client { |
return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING; |
} |
- bool have_immediate_requests_in_flight = |
- in_flight_requests_.size() > in_flight_delayable_count_; |
- if (have_immediate_requests_in_flight && |
- (!has_body_ || total_layout_blocking_count_ != 0) && |
- // Do not allow a low priority request through in parallel if |
- // we are in a limit field trial. |
- (scheduler_->limit_outstanding_requests() || |
- in_flight_delayable_count_ != 0)) { |
- return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; |
+ if (!has_body_ || total_layout_blocking_count_ != 0) { |
+ // Layout-blocking phase of resource loading |
mmenke
2015/08/07 16:55:10
Add period (More consistent with other comments he
mmenke
2015/08/07 16:55:11
Suggest comment above the if (I find it easier to
Pat Meenan
2015/08/07 20:48:09
Done.
|
+ size_t immediate_requests_in_flight_count = |
mmenke
2015/08/07 16:55:11
non_delayable_...?
Pat Meenan
2015/08/07 20:48:09
Done.
|
+ in_flight_requests_.size() - in_flight_delayable_count_; |
+ if (enable_layout_blocking_threshold_) { |
+ if (immediate_requests_in_flight_count > |
+ in_flight_layout_blocking_threshold_) { |
+ // Too many higher priority in-flight requests to allow lower priority |
+ // requests through. |
+ return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; |
+ } |
+ if (in_flight_requests_.size() > 0 && |
mmenke
2015/08/07 16:55:11
The other branch only does this if immediate_reque
Pat Meenan
2015/08/07 20:48:09
The difference between the two is pretty significa
|
+ // Allow the request if nothing is in flight or if the limit of |
+ // concurrent lower priority requests has not been hit. |
+ (scheduler_->limit_outstanding_requests() || |
+ in_flight_delayable_count_ >= |
+ max_num_delayable_while_layout_blocking_)) { |
+ return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; |
+ } |
+ } else if (immediate_requests_in_flight_count > 0 && |
mmenke
2015/08/07 16:55:11
if "total_layout_blocking_count_" is greater than
Pat Meenan
2015/08/07 20:48:09
Sadly, no. This is where the middle group of requ
mmenke
2015/08/07 20:56:02
Oh, I missed that this block is "!has_body_ || tot
|
+ // If there are no high-priority requests in flight the floodgates |
+ // open. |
+ // If there are high-priority requests in-flight then limit the number |
+ // of lower-priority requests (or zero if a limit field trial is |
+ // active). |
+ (scheduler_->limit_outstanding_requests() || |
+ in_flight_delayable_count_ >= |
+ max_num_delayable_while_layout_blocking_)) { |
+ return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; |
+ } |
} |
return START_REQUEST; |
@@ -851,6 +912,11 @@ class ResourceScheduler::Client { |
// The number of layout-blocking in-flight requests. |
size_t total_layout_blocking_count_; |
ResourceScheduler::ClientThrottleState throttle_state_; |
+ size_t max_num_delayable_requests_; |
+ size_t max_num_delayable_while_layout_blocking_; |
+ bool enable_layout_blocking_threshold_; |
+ size_t in_flight_layout_blocking_threshold_; |
+ net::RequestPriority layout_blocking_priority_threshold_; |
mmenke
2015/08/07 16:55:10
These really need docs, and could use clearer name
Pat Meenan
2015/08/07 20:48:10
Added docs. Let me know if threshold still doesn'
|
}; |
ResourceScheduler::ResourceScheduler() |