Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: components/domain_reliability/scheduler.cc

Issue 709333003: Revert of Domain Reliability: Switch to BackoffEntry in Scheduler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@parse_retry_after_header
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/domain_reliability/scheduler.h" 5 #include "components/domain_reliability/scheduler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/metrics/field_trial.h" 9 #include "base/metrics/field_trial.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/values.h" 11 #include "base/values.h"
12 #include "components/domain_reliability/config.h" 12 #include "components/domain_reliability/config.h"
13 #include "components/domain_reliability/util.h" 13 #include "components/domain_reliability/util.h"
14 14
15 namespace { 15 namespace {
16 16
17 const unsigned kInvalidCollectorIndex = static_cast<unsigned>(-1); 17 const unsigned kInvalidCollectorIndex = static_cast<unsigned>(-1);
18 18
19 const unsigned kDefaultMinimumUploadDelaySec = 60; 19 const unsigned kDefaultMinimumUploadDelaySec = 60;
20 const unsigned kDefaultMaximumUploadDelaySec = 300; 20 const unsigned kDefaultMaximumUploadDelaySec = 300;
21 const unsigned kDefaultUploadRetryIntervalSec = 60; 21 const unsigned kDefaultUploadRetryIntervalSec = 60;
22 22
23 const char* kMinimumUploadDelayFieldTrialName = "DomRel-MinimumUploadDelay"; 23 const char* kMinimumUploadDelayFieldTrialName = "DomRel-MinimumUploadDelay";
24 const char* kMaximumUploadDelayFieldTrialName = "DomRel-MaximumUploadDelay"; 24 const char* kMaximumUploadDelayFieldTrialName = "DomRel-MaximumUploadDelay";
25 const char* kUploadRetryIntervalFieldTrialName = "DomRel-UploadRetryInterval"; 25 const char* kUploadRetryIntervalFieldTrialName = "DomRel-UploadRetryInterval";
26 26
27 // Fixed elements of backoff policy
28 const double kMultiplyFactor = 2.0;
29 const double kJitterFactor = 0.1;
30 const int64 kMaximumBackoffMs = 60 * 1000 * 1000;
31
32 unsigned GetUnsignedFieldTrialValueOrDefault(std::string field_trial_name, 27 unsigned GetUnsignedFieldTrialValueOrDefault(std::string field_trial_name,
33 unsigned default_value) { 28 unsigned default_value) {
34 if (!base::FieldTrialList::TrialExists(field_trial_name)) 29 if (!base::FieldTrialList::TrialExists(field_trial_name))
35 return default_value; 30 return default_value;
36 31
37 std::string group_name = base::FieldTrialList::FindFullName(field_trial_name); 32 std::string group_name = base::FieldTrialList::FindFullName(field_trial_name);
38 unsigned value; 33 unsigned value;
39 if (!base::StringToUint(group_name, &value)) { 34 if (!base::StringToUint(group_name, &value)) {
40 LOG(ERROR) << "Expected unsigned integer for field trial " 35 LOG(ERROR) << "Expected unsigned integer for field trial "
41 << field_trial_name << " group name, but got \"" << group_name 36 << field_trial_name << " group name, but got \"" << group_name
(...skipping 25 matching lines...) Expand all
67 62
68 return params; 63 return params;
69 } 64 }
70 65
71 DomainReliabilityScheduler::DomainReliabilityScheduler( 66 DomainReliabilityScheduler::DomainReliabilityScheduler(
72 MockableTime* time, 67 MockableTime* time,
73 size_t num_collectors, 68 size_t num_collectors,
74 const Params& params, 69 const Params& params,
75 const ScheduleUploadCallback& callback) 70 const ScheduleUploadCallback& callback)
76 : time_(time), 71 : time_(time),
72 collectors_(num_collectors),
77 params_(params), 73 params_(params),
78 callback_(callback), 74 callback_(callback),
79 upload_pending_(false), 75 upload_pending_(false),
80 upload_scheduled_(false), 76 upload_scheduled_(false),
81 upload_running_(false), 77 upload_running_(false),
82 collector_index_(kInvalidCollectorIndex), 78 collector_index_(kInvalidCollectorIndex),
83 last_upload_finished_(false) { 79 last_upload_finished_(false) {
84 backoff_policy_.num_errors_to_ignore = 0;
85 backoff_policy_.initial_delay_ms =
86 params.upload_retry_interval.InMilliseconds();
87 backoff_policy_.multiply_factor = kMultiplyFactor;
88 backoff_policy_.jitter_factor = kJitterFactor;
89 backoff_policy_.maximum_backoff_ms = kMaximumBackoffMs;
90 backoff_policy_.entry_lifetime_ms = 0;
91 backoff_policy_.always_use_initial_delay = false;
92
93 for (size_t i = 0; i < num_collectors; ++i) {
94 collectors_.push_back(
95 new MockableTimeBackoffEntry(&backoff_policy_, time_));
96 }
97 } 80 }
98 81
99 DomainReliabilityScheduler::~DomainReliabilityScheduler() {} 82 DomainReliabilityScheduler::~DomainReliabilityScheduler() {}
100 83
101 void DomainReliabilityScheduler::OnBeaconAdded() { 84 void DomainReliabilityScheduler::OnBeaconAdded() {
102 if (!upload_pending_) 85 if (!upload_pending_)
103 first_beacon_time_ = time_->NowTicks(); 86 first_beacon_time_ = time_->NowTicks();
104 upload_pending_ = true; 87 upload_pending_ = true;
105 MaybeScheduleUpload(); 88 MaybeScheduleUpload();
106 } 89 }
(...skipping 19 matching lines...) Expand all
126 } 109 }
127 110
128 void DomainReliabilityScheduler::OnUploadComplete(bool success) { 111 void DomainReliabilityScheduler::OnUploadComplete(bool success) {
129 DCHECK(upload_running_); 112 DCHECK(upload_running_);
130 DCHECK_NE(kInvalidCollectorIndex, collector_index_); 113 DCHECK_NE(kInvalidCollectorIndex, collector_index_);
131 upload_running_ = false; 114 upload_running_ = false;
132 115
133 VLOG(1) << "Upload to collector " << collector_index_ 116 VLOG(1) << "Upload to collector " << collector_index_
134 << (success ? " succeeded." : " failed."); 117 << (success ? " succeeded." : " failed.");
135 118
136 net::BackoffEntry* backoff = collectors_[collector_index_]; 119 CollectorState* collector = &collectors_[collector_index_];
137 collector_index_ = kInvalidCollectorIndex; 120 collector_index_ = kInvalidCollectorIndex;
138 backoff->InformOfRequest(success);
139 121
140 if (!success) { 122 if (success) {
123 collector->failures = 0;
124 } else {
141 // Restore upload_pending_ and first_beacon_time_ to pre-upload state, 125 // Restore upload_pending_ and first_beacon_time_ to pre-upload state,
142 // since upload failed. 126 // since upload failed.
143 upload_pending_ = true; 127 upload_pending_ = true;
144 first_beacon_time_ = old_first_beacon_time_; 128 first_beacon_time_ = old_first_beacon_time_;
129
130 ++collector->failures;
145 } 131 }
146 132
147 last_upload_end_time_ = time_->NowTicks(); 133 base::TimeTicks now = time_->NowTicks();
134 base::TimeDelta retry_interval = GetUploadRetryInterval(collector->failures);
135 collector->next_upload = now + retry_interval;
136
137 last_upload_end_time_ = now;
148 last_upload_success_ = success; 138 last_upload_success_ = success;
149 last_upload_finished_ = true; 139 last_upload_finished_ = true;
150 140
141 VLOG(1) << "Next upload to collector at least "
142 << retry_interval.InSeconds() << " seconds from now.";
143
151 MaybeScheduleUpload(); 144 MaybeScheduleUpload();
152 } 145 }
153 146
154 base::Value* DomainReliabilityScheduler::GetWebUIData() const { 147 base::Value* DomainReliabilityScheduler::GetWebUIData() const {
155 base::TimeTicks now = time_->NowTicks(); 148 base::TimeTicks now = time_->NowTicks();
156 149
157 base::DictionaryValue* data = new base::DictionaryValue(); 150 base::DictionaryValue* data = new base::DictionaryValue();
158 151
159 data->SetBoolean("upload_pending", upload_pending_); 152 data->SetBoolean("upload_pending", upload_pending_);
160 data->SetBoolean("upload_scheduled", upload_scheduled_); 153 data->SetBoolean("upload_scheduled", upload_scheduled_);
161 data->SetBoolean("upload_running", upload_running_); 154 data->SetBoolean("upload_running", upload_running_);
162 155
163 data->SetInteger("scheduled_min", (scheduled_min_time_ - now).InSeconds()); 156 data->SetInteger("scheduled_min", (scheduled_min_time_ - now).InSeconds());
164 data->SetInteger("scheduled_max", (scheduled_max_time_ - now).InSeconds()); 157 data->SetInteger("scheduled_max", (scheduled_max_time_ - now).InSeconds());
165 158
166 data->SetInteger("collector_index", static_cast<int>(collector_index_)); 159 data->SetInteger("collector_index", static_cast<int>(collector_index_));
167 160
168 if (last_upload_finished_) { 161 if (last_upload_finished_) {
169 base::DictionaryValue* last = new base::DictionaryValue(); 162 base::DictionaryValue* last = new base::DictionaryValue();
170 last->SetInteger("start_time", (now - last_upload_start_time_).InSeconds()); 163 last->SetInteger("start_time", (now - last_upload_start_time_).InSeconds());
171 last->SetInteger("end_time", (now - last_upload_end_time_).InSeconds()); 164 last->SetInteger("end_time", (now - last_upload_end_time_).InSeconds());
172 last->SetInteger("collector_index", 165 last->SetInteger("collector_index",
173 static_cast<int>(last_upload_collector_index_)); 166 static_cast<int>(last_upload_collector_index_));
174 last->SetBoolean("success", last_upload_success_); 167 last->SetBoolean("success", last_upload_success_);
175 data->Set("last_upload", last); 168 data->Set("last_upload", last);
176 } 169 }
177 170
178 base::ListValue* collectors = new base::ListValue(); 171 base::ListValue* collectors = new base::ListValue();
179 for (size_t i = 0; i < collectors_.size(); ++i) { 172 for (size_t i = 0; i < collectors_.size(); ++i) {
180 const net::BackoffEntry* backoff = collectors_[i]; 173 const CollectorState* state = &collectors_[i];
181 base::DictionaryValue* value = new base::DictionaryValue(); 174 base::DictionaryValue* value = new base::DictionaryValue();
182 value->SetInteger("failures", backoff->failure_count()); 175 value->SetInteger("failures", state->failures);
183 value->SetInteger("next_upload", 176 value->SetInteger("next_upload", (state->next_upload - now).InSeconds());
184 (backoff->GetReleaseTime() - now).InSeconds());
185 collectors->Append(value); 177 collectors->Append(value);
186 } 178 }
187 data->Set("collectors", collectors); 179 data->Set("collectors", collectors);
188 180
189 return data; 181 return data;
190 } 182 }
191 183
192 void DomainReliabilityScheduler::MakeDeterministicForTesting() { 184 DomainReliabilityScheduler::CollectorState::CollectorState() : failures(0) {}
193 backoff_policy_.jitter_factor = 0.0;
194 }
195 185
196 void DomainReliabilityScheduler::MaybeScheduleUpload() { 186 void DomainReliabilityScheduler::MaybeScheduleUpload() {
197 if (!upload_pending_ || upload_scheduled_ || upload_running_) 187 if (!upload_pending_ || upload_scheduled_ || upload_running_)
198 return; 188 return;
199 189
200 upload_scheduled_ = true; 190 upload_scheduled_ = true;
201 old_first_beacon_time_ = first_beacon_time_; 191 old_first_beacon_time_ = first_beacon_time_;
202 192
203 base::TimeTicks now = time_->NowTicks(); 193 base::TimeTicks now = time_->NowTicks();
204 194
(...skipping 26 matching lines...) Expand all
231 base::TimeTicks now, 221 base::TimeTicks now,
232 base::TimeTicks* upload_time_out, 222 base::TimeTicks* upload_time_out,
233 size_t* collector_index_out) { 223 size_t* collector_index_out) {
234 DCHECK(upload_time_out); 224 DCHECK(upload_time_out);
235 DCHECK(collector_index_out); 225 DCHECK(collector_index_out);
236 226
237 base::TimeTicks min_time; 227 base::TimeTicks min_time;
238 size_t min_index = kInvalidCollectorIndex; 228 size_t min_index = kInvalidCollectorIndex;
239 229
240 for (size_t i = 0; i < collectors_.size(); ++i) { 230 for (size_t i = 0; i < collectors_.size(); ++i) {
241 net::BackoffEntry* backoff = collectors_[i]; 231 CollectorState* collector = &collectors_[i];
242 // If a collector is usable, use the first one in the list. 232 // If a collector is usable, use the first one in the list.
243 if (!backoff->ShouldRejectRequest()) { 233 if (collector->failures == 0 || collector->next_upload <= now) {
244 min_time = now; 234 min_time = now;
245 min_index = i; 235 min_index = i;
246 break; 236 break;
247 }
248
249 // If not, keep track of which will be usable soonest: 237 // If not, keep track of which will be usable soonest:
250 base::TimeTicks time = backoff->GetReleaseTime(); 238 } else if (min_index == kInvalidCollectorIndex ||
251 if (min_index == kInvalidCollectorIndex || time < min_time) { 239 collector->next_upload < min_time) {
252 min_time = time; 240 min_time = collector->next_upload;
253 min_index = i; 241 min_index = i;
254 } 242 }
255 } 243 }
256 244
257 DCHECK_NE(kInvalidCollectorIndex, min_index); 245 DCHECK_NE(kInvalidCollectorIndex, min_index);
258 *upload_time_out = min_time; 246 *upload_time_out = min_time;
259 *collector_index_out = min_index; 247 *collector_index_out = min_index;
260 } 248 }
261 249
250 base::TimeDelta DomainReliabilityScheduler::GetUploadRetryInterval(
251 unsigned failures) {
252 if (failures == 0)
253 return base::TimeDelta::FromSeconds(0);
254 else {
255 // Don't back off more than 64x the original delay.
256 if (failures > 7)
257 failures = 7;
258 return params_.upload_retry_interval * (1 << (failures - 1));
259 }
260 }
261
262 } // namespace domain_reliability 262 } // namespace domain_reliability
OLDNEW
« no previous file with comments | « components/domain_reliability/scheduler.h ('k') | components/domain_reliability/scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698