Commit 02472a20 authored by Tarun Bansal's avatar Tarun Bansal Committed by Commit Bot

Resource Scheduler: Enable ThrottleDelayable experiment

This experiment throttles low priority requests based on the
count of high priority requests and the current network quality.
The experiment changes the scheduling behavior only when
the current effective connection type is Slow2G or 2G.

The code to adapt the scheduling behavior based on ECT
is still there in the ResourceScheduler in case we need to
revert it or update the params using finch.

Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: I77ba950344e6ff8e05a83ebb0dc5b48cec6ff3c8
Bug: 746640
Reviewed-on: https://chromium-review.googlesource.com/955703Reviewed-by: default avatarMark Pearson <mpearson@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Reviewed-by: default avatarRyan Sturm <ryansturm@chromium.org>
Commit-Queue: Tarun Bansal <tbansal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542742}
parent 29f8841c
...@@ -1257,6 +1257,11 @@ ResourceScheduler::ThrottleDelayable::GetParamsForNetworkQualityContainer() { ...@@ -1257,6 +1257,11 @@ ResourceScheduler::ThrottleDelayable::GetParamsForNetworkQualityContainer() {
static const char kNonDelayableWeightBase[] = "NonDelayableWeight"; static const char kNonDelayableWeightBase[] = "NonDelayableWeight";
ParamsForNetworkQualityContainer result; ParamsForNetworkQualityContainer result;
// Set the default params for networks with ECT Slow2G and 2G. These params
// can still be overridden using the field trial.
result.push_back({net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G, 8, 3});
result.push_back({net::EFFECTIVE_CONNECTION_TYPE_2G, 8, 3});
if (!base::FeatureList::IsEnabled(kThrottleDelayable)) if (!base::FeatureList::IsEnabled(kThrottleDelayable))
return result; return result;
...@@ -1290,8 +1295,22 @@ ResourceScheduler::ThrottleDelayable::GetParamsForNetworkQualityContainer() { ...@@ -1290,8 +1295,22 @@ ResourceScheduler::ThrottleDelayable::GetParamsForNetworkQualityContainer() {
return result; return result;
} }
result.push_back({effective_connection_type.value(), max_delayable_requests, // Check if the entry is already present. This will happen if the default
non_delayable_weight}); // params are being overridden by the field trial.
bool entry_found = false;
for (auto& range : result) {
if (effective_connection_type == range.effective_connection_type) {
range.max_delayable_requests = max_delayable_requests;
range.non_delayable_weight = non_delayable_weight;
entry_found = true;
break;
}
}
if (!entry_found) {
result.push_back({effective_connection_type.value(),
max_delayable_requests, non_delayable_weight});
}
config_param_index++; config_param_index++;
} }
} }
......
...@@ -281,7 +281,7 @@ class ResourceSchedulerTest : public testing::Test { ...@@ -281,7 +281,7 @@ class ResourceSchedulerTest : public testing::Test {
experiment_status, 0.0); experiment_status, 0.0);
// Set the effective connection type to Slow-2G, which is slower than the // Set the effective connection type to Slow-2G, which is slower than the
// threshold configured in |InitializeMaxDelayableRequestsExperiment|. Needs // threshold configured in |InitializeThrottleDelayableExperiment|. Needs
// to be done before initializing the scheduler because the client is // to be done before initializing the scheduler because the client is
// created on the call to |InitializeScheduler|, which is where the initial // created on the call to |InitializeScheduler|, which is where the initial
// limits for the delayable requests in flight are computed. // limits for the delayable requests in flight are computed.
...@@ -303,7 +303,7 @@ class ResourceSchedulerTest : public testing::Test { ...@@ -303,7 +303,7 @@ class ResourceSchedulerTest : public testing::Test {
EXPECT_TRUE(high2->started()); EXPECT_TRUE(high2->started());
// Should match the configuration set by // Should match the configuration set by
// |InitializeMaxDelayableRequestsExperiment| // |InitializeThrottleDelayableExperiment|
const int kOverriddenNumRequests = 2; const int kOverriddenNumRequests = 2;
std::vector<std::unique_ptr<TestRequest>> lows_singlehost; std::vector<std::unique_ptr<TestRequest>> lows_singlehost;
...@@ -366,7 +366,7 @@ class ResourceSchedulerTest : public testing::Test { ...@@ -366,7 +366,7 @@ class ResourceSchedulerTest : public testing::Test {
experiment_enabled = true; experiment_enabled = true;
params["EffectiveConnectionType1"] = "Slow-2G"; params["EffectiveConnectionType1"] = "Slow-2G";
if (params["MaxDelayableRequests1"] == "") if (params["MaxDelayableRequests1"] == "")
params["MaxDelayableRequests1"] = "10"; params["MaxDelayableRequests1"] = "8";
params["NonDelayableWeight1"] = params["NonDelayableWeight1"] =
base::NumberToString(non_delayable_weight); base::NumberToString(non_delayable_weight);
} }
...@@ -395,26 +395,38 @@ class ResourceSchedulerTest : public testing::Test { ...@@ -395,26 +395,38 @@ class ResourceSchedulerTest : public testing::Test {
ResourceScheduler::GetParamsForNetworkQualityContainerForTests(); ResourceScheduler::GetParamsForNetworkQualityContainerForTests();
if (!lower_delayable_count_enabled && non_delayable_weight <= 0.0) { if (!lower_delayable_count_enabled && non_delayable_weight <= 0.0) {
ASSERT_EQ(0u, params_network_quality_container.size()); ASSERT_EQ(2u, params_network_quality_container.size());
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
params_network_quality_container[0].effective_connection_type);
EXPECT_EQ(8u, params_network_quality_container[0].max_delayable_requests);
EXPECT_EQ(3.0, params_network_quality_container[0].non_delayable_weight);
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G,
params_network_quality_container[1].effective_connection_type);
EXPECT_EQ(8u, params_network_quality_container[1].max_delayable_requests);
EXPECT_EQ(3.0, params_network_quality_container[1].non_delayable_weight);
return; return;
} }
// Check that the configuration was parsed and stored correctly. // Check that the configuration was parsed and stored correctly.
ASSERT_EQ(lower_delayable_count_enabled ? 2u : 1u, ASSERT_EQ(lower_delayable_count_enabled ? 3u : 2u,
params_network_quality_container.size()); params_network_quality_container.size());
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G, EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
params_network_quality_container[0].effective_connection_type); params_network_quality_container[0].effective_connection_type);
EXPECT_EQ(non_delayable_weight > 0.0 ? 10u : 2u, EXPECT_EQ(non_delayable_weight > 0.0 ? 8u : 2u,
params_network_quality_container[0].max_delayable_requests); params_network_quality_container[0].max_delayable_requests);
EXPECT_EQ(non_delayable_weight > 0.0 ? non_delayable_weight : 0.0, EXPECT_EQ(non_delayable_weight > 0.0 ? non_delayable_weight : 0.0,
params_network_quality_container[0].non_delayable_weight); params_network_quality_container[0].non_delayable_weight);
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G,
params_network_quality_container[1].effective_connection_type);
if (lower_delayable_count_enabled) { if (lower_delayable_count_enabled) {
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G, EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G,
params_network_quality_container[1].effective_connection_type); params_network_quality_container[2].effective_connection_type);
EXPECT_EQ(4u, params_network_quality_container[1].max_delayable_requests); EXPECT_EQ(4u, params_network_quality_container[2].max_delayable_requests);
EXPECT_EQ(0.0, params_network_quality_container[1].non_delayable_weight); EXPECT_EQ(0.0, params_network_quality_container[2].non_delayable_weight);
} }
} }
...@@ -450,23 +462,38 @@ class ResourceSchedulerTest : public testing::Test { ...@@ -450,23 +462,38 @@ class ResourceSchedulerTest : public testing::Test {
ResourceScheduler::GetParamsForNetworkQualityContainerForTests(); ResourceScheduler::GetParamsForNetworkQualityContainerForTests();
// Check that the configuration was parsed and stored correctly. // Check that the configuration was parsed and stored correctly.
ASSERT_EQ(params_network_quality_container.size(), num_ranges); ASSERT_EQ(std::max(static_cast<size_t>(2u), num_ranges),
for (size_t index = 1; index <= num_ranges; index++) { params_network_quality_container.size());
for (size_t index = 1; index <= params_network_quality_container.size();
index++) {
EXPECT_EQ(1 + index, EXPECT_EQ(1 + index,
static_cast<size_t>(params_network_quality_container[index - 1] static_cast<size_t>(params_network_quality_container[index - 1]
.effective_connection_type)); .effective_connection_type));
EXPECT_EQ( if (params_network_quality_container[index - 1]
index * 10u, .effective_connection_type <=
params_network_quality_container[index - 1].max_delayable_requests); net::EFFECTIVE_CONNECTION_TYPE_2G &&
EXPECT_EQ( num_ranges < index) {
0, params_network_quality_container[index - 1].non_delayable_weight); EXPECT_EQ(
8u,
params_network_quality_container[index - 1].max_delayable_requests);
EXPECT_EQ(
3,
params_network_quality_container[index - 1].non_delayable_weight);
} else {
EXPECT_EQ(
index * 10u,
params_network_quality_container[index - 1].max_delayable_requests);
EXPECT_EQ(
0,
params_network_quality_container[index - 1].non_delayable_weight);
}
} }
} }
void NonDelayableThrottlesDelayableHelper(double non_delayable_weight) { void NonDelayableThrottlesDelayableHelper(double non_delayable_weight) {
base::test::ScopedFeatureList scoped_feature_list; base::test::ScopedFeatureList scoped_feature_list;
// Should be in sync with .cc. // Should be in sync with .cc for ECT SLOW_2G,
const int kDefaultMaxNumDelayableRequestsPerClient = 10; const int kDefaultMaxNumDelayableRequestsPerClient = 8;
// Initialize the experiment. // Initialize the experiment.
InitializeThrottleDelayableExperiment(&scoped_feature_list, false, InitializeThrottleDelayableExperiment(&scoped_feature_list, false,
non_delayable_weight); non_delayable_weight);
...@@ -1598,7 +1625,7 @@ TEST_F(ResourceSchedulerTest, RequestLimitOverrideFixedForPageLoad) { ...@@ -1598,7 +1625,7 @@ TEST_F(ResourceSchedulerTest, RequestLimitOverrideFixedForPageLoad) {
EXPECT_TRUE(high->started()); EXPECT_TRUE(high->started());
// Should be based on the value set by // Should be based on the value set by
// |InitializeMaxDelayableRequestsExperiment| for the given range. // |InitializeThrottleDelayableExperiment| for the given range.
const int kOverriddenNumRequests = 2; const int kOverriddenNumRequests = 2;
std::vector<std::unique_ptr<TestRequest>> lows_singlehost; std::vector<std::unique_ptr<TestRequest>> lows_singlehost;
...@@ -1791,11 +1818,16 @@ TEST_F(ResourceSchedulerTest, ReadInvalidConfigTest) { ...@@ -1791,11 +1818,16 @@ TEST_F(ResourceSchedulerTest, ReadInvalidConfigTest) {
// Only the first configuration parameter must be read because a match was not // Only the first configuration parameter must be read because a match was not
// found for index 2. The configuration parameters with index 3 and 4 must be // found for index 2. The configuration parameters with index 3 and 4 must be
// ignored, even though they are valid configuration parameters. // ignored, even though they are valid configuration parameters.
EXPECT_EQ(1u, params_network_quality_container.size()); EXPECT_EQ(2u, params_network_quality_container.size());
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G, EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
params_network_quality_container[0].effective_connection_type); params_network_quality_container[0].effective_connection_type);
EXPECT_EQ(10u, params_network_quality_container[0].max_delayable_requests); EXPECT_EQ(10u, params_network_quality_container[0].max_delayable_requests);
EXPECT_EQ(0.0, params_network_quality_container[0].non_delayable_weight); EXPECT_EQ(0.0, params_network_quality_container[0].non_delayable_weight);
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G,
params_network_quality_container[1].effective_connection_type);
EXPECT_EQ(8u, params_network_quality_container[1].max_delayable_requests);
EXPECT_EQ(3.0, params_network_quality_container[1].non_delayable_weight);
} }
// Test that the default limit is used for delayable requests when the // Test that the default limit is used for delayable requests when the
...@@ -1841,7 +1873,7 @@ TEST_F(ResourceSchedulerTest, NonDelayableThrottlesDelayableVaryNonDelayable) { ...@@ -1841,7 +1873,7 @@ TEST_F(ResourceSchedulerTest, NonDelayableThrottlesDelayableVaryNonDelayable) {
base::test::ScopedFeatureList scoped_feature_list; base::test::ScopedFeatureList scoped_feature_list;
const double kNonDelayableWeight = 2.0; const double kNonDelayableWeight = 2.0;
const int kDefaultMaxNumDelayableRequestsPerClient = const int kDefaultMaxNumDelayableRequestsPerClient =
10; // Should be in sync with cc. 8; // Should be in sync with cc.
// Initialize the experiment with |kNonDelayableWeight| as the weight of // Initialize the experiment with |kNonDelayableWeight| as the weight of
// non-delayable requests. // non-delayable requests.
InitializeThrottleDelayableExperiment(&scoped_feature_list, false, InitializeThrottleDelayableExperiment(&scoped_feature_list, false,
...@@ -1879,12 +1911,6 @@ TEST_F(ResourceSchedulerTest, NonDelayableThrottlesDelayableVaryNonDelayable) { ...@@ -1879,12 +1911,6 @@ TEST_F(ResourceSchedulerTest, NonDelayableThrottlesDelayableVaryNonDelayable) {
} }
} }
// Test that the default limit is used for delayable requests in the presence of
// non-delayable requests when the non-delayable request weight is zero.
TEST_F(ResourceSchedulerTest, NonDelayableThrottlesDelayableWeight0) {
NonDelayableThrottlesDelayableHelper(0.0);
}
// Test that each non-delayable request in-flight results in the reduction of // Test that each non-delayable request in-flight results in the reduction of
// one in the limit of delayable requests in-flight when the non-delayable // one in the limit of delayable requests in-flight when the non-delayable
// request weight is 1. // request weight is 1.
......
...@@ -3693,15 +3693,9 @@ ...@@ -3693,15 +3693,9 @@
{ {
"name": "Enabled", "name": "Enabled",
"params": { "params": {
"EffectiveConnectionType1": "Slow-2G", "EffectiveConnectionType1": "3G",
"EffectiveConnectionType2": "2G", "MaxDelayableRequests1": "14",
"EffectiveConnectionType3": "3G", "NonDelayableWeight1": "2.0"
"MaxDelayableRequests1": "8",
"MaxDelayableRequests2": "8",
"MaxDelayableRequests3": "14",
"NonDelayableWeight1": "2.0",
"NonDelayableWeight2": "2.0",
"NonDelayableWeight3": "2.0"
}, },
"enable_features": [ "enable_features": [
"ThrottleDelayable" "ThrottleDelayable"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment