OLD | NEW |
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 "components/domain_reliability/config.h" | 12 #include "components/domain_reliability/config.h" |
12 #include "components/domain_reliability/util.h" | 13 #include "components/domain_reliability/util.h" |
13 | 14 |
14 namespace { | 15 namespace { |
15 | 16 |
16 const unsigned kInvalidCollectorIndex = -1; | 17 const unsigned kInvalidCollectorIndex = -1; |
17 | 18 |
18 const unsigned kDefaultMinimumUploadDelaySec = 60; | 19 const unsigned kDefaultMinimumUploadDelaySec = 60; |
19 const unsigned kDefaultMaximumUploadDelaySec = 300; | 20 const unsigned kDefaultMaximumUploadDelaySec = 300; |
20 const unsigned kDefaultUploadRetryIntervalSec = 60; | 21 const unsigned kDefaultUploadRetryIntervalSec = 60; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 size_t num_collectors, | 68 size_t num_collectors, |
68 const Params& params, | 69 const Params& params, |
69 const ScheduleUploadCallback& callback) | 70 const ScheduleUploadCallback& callback) |
70 : time_(time), | 71 : time_(time), |
71 collectors_(num_collectors), | 72 collectors_(num_collectors), |
72 params_(params), | 73 params_(params), |
73 callback_(callback), | 74 callback_(callback), |
74 upload_pending_(false), | 75 upload_pending_(false), |
75 upload_scheduled_(false), | 76 upload_scheduled_(false), |
76 upload_running_(false), | 77 upload_running_(false), |
77 collector_index_(kInvalidCollectorIndex) { | 78 collector_index_(kInvalidCollectorIndex), |
| 79 last_upload_finished_(false) { |
78 } | 80 } |
79 | 81 |
80 DomainReliabilityScheduler::~DomainReliabilityScheduler() {} | 82 DomainReliabilityScheduler::~DomainReliabilityScheduler() {} |
81 | 83 |
82 void DomainReliabilityScheduler::OnBeaconAdded() { | 84 void DomainReliabilityScheduler::OnBeaconAdded() { |
83 if (!upload_pending_) | 85 if (!upload_pending_) |
84 first_beacon_time_ = time_->NowTicks(); | 86 first_beacon_time_ = time_->NowTicks(); |
85 upload_pending_ = true; | 87 upload_pending_ = true; |
86 MaybeScheduleUpload(); | 88 MaybeScheduleUpload(); |
87 } | 89 } |
88 | 90 |
89 size_t DomainReliabilityScheduler::OnUploadStart() { | 91 size_t DomainReliabilityScheduler::OnUploadStart() { |
90 DCHECK(upload_scheduled_); | 92 DCHECK(upload_scheduled_); |
91 DCHECK_EQ(kInvalidCollectorIndex, collector_index_); | 93 DCHECK_EQ(kInvalidCollectorIndex, collector_index_); |
92 upload_pending_ = false; | 94 upload_pending_ = false; |
93 upload_scheduled_ = false; | 95 upload_scheduled_ = false; |
94 upload_running_ = true; | 96 upload_running_ = true; |
95 | 97 |
96 base::TimeTicks now = time_->NowTicks(); | 98 base::TimeTicks now = time_->NowTicks(); |
97 base::TimeTicks min_upload_time; | 99 base::TimeTicks min_upload_time; |
98 GetNextUploadTimeAndCollector(now, &min_upload_time, &collector_index_); | 100 GetNextUploadTimeAndCollector(now, &min_upload_time, &collector_index_); |
99 DCHECK(min_upload_time <= now); | 101 DCHECK(min_upload_time <= now); |
100 | 102 |
101 VLOG(1) << "Starting upload to collector " << collector_index_ << "."; | 103 VLOG(1) << "Starting upload to collector " << collector_index_ << "."; |
102 | 104 |
| 105 last_upload_start_time_ = now; |
| 106 last_upload_collector_index_ = collector_index_; |
| 107 |
103 return collector_index_; | 108 return collector_index_; |
104 } | 109 } |
105 | 110 |
106 void DomainReliabilityScheduler::OnUploadComplete(bool success) { | 111 void DomainReliabilityScheduler::OnUploadComplete(bool success) { |
107 DCHECK(upload_running_); | 112 DCHECK(upload_running_); |
108 DCHECK_NE(kInvalidCollectorIndex, collector_index_); | 113 DCHECK_NE(kInvalidCollectorIndex, collector_index_); |
109 upload_running_ = false; | 114 upload_running_ = false; |
110 | 115 |
111 VLOG(1) << "Upload to collector " << collector_index_ | 116 VLOG(1) << "Upload to collector " << collector_index_ |
112 << (success ? " succeeded." : " failed."); | 117 << (success ? " succeeded." : " failed."); |
113 | 118 |
114 CollectorState* collector = &collectors_[collector_index_]; | 119 CollectorState* collector = &collectors_[collector_index_]; |
115 collector_index_ = kInvalidCollectorIndex; | 120 collector_index_ = kInvalidCollectorIndex; |
116 | 121 |
117 if (success) { | 122 if (success) { |
118 collector->failures = 0; | 123 collector->failures = 0; |
119 } else { | 124 } else { |
120 // Restore upload_pending_ and first_beacon_time_ to pre-upload state, | 125 // Restore upload_pending_ and first_beacon_time_ to pre-upload state, |
121 // since upload failed. | 126 // since upload failed. |
122 upload_pending_ = true; | 127 upload_pending_ = true; |
123 first_beacon_time_ = old_first_beacon_time_; | 128 first_beacon_time_ = old_first_beacon_time_; |
124 | 129 |
125 ++collector->failures; | 130 ++collector->failures; |
126 } | 131 } |
127 | 132 |
| 133 base::TimeTicks now = time_->NowTicks(); |
128 base::TimeDelta retry_interval = GetUploadRetryInterval(collector->failures); | 134 base::TimeDelta retry_interval = GetUploadRetryInterval(collector->failures); |
129 collector->next_upload = time_->NowTicks() + retry_interval; | 135 collector->next_upload = now + retry_interval; |
| 136 |
| 137 last_upload_end_time_ = now; |
| 138 last_upload_success_ = success; |
| 139 last_upload_finished_ = true; |
130 | 140 |
131 VLOG(1) << "Next upload to collector at least " | 141 VLOG(1) << "Next upload to collector at least " |
132 << retry_interval.InSeconds() << " seconds from now."; | 142 << retry_interval.InSeconds() << " seconds from now."; |
133 | 143 |
134 MaybeScheduleUpload(); | 144 MaybeScheduleUpload(); |
135 } | 145 } |
136 | 146 |
| 147 base::Value* DomainReliabilityScheduler::GetWebUIData() const { |
| 148 base::TimeTicks now = time_->NowTicks(); |
| 149 |
| 150 base::DictionaryValue* data = new base::DictionaryValue(); |
| 151 |
| 152 data->SetBoolean("upload_pending", upload_pending_); |
| 153 data->SetBoolean("upload_scheduled", upload_scheduled_); |
| 154 data->SetBoolean("upload_running", upload_running_); |
| 155 |
| 156 data->SetInteger("scheduled_min", (scheduled_min_time_ - now).InSeconds()); |
| 157 data->SetInteger("scheduled_max", (scheduled_max_time_ - now).InSeconds()); |
| 158 |
| 159 data->SetInteger("collector_index", collector_index_); |
| 160 |
| 161 if (last_upload_finished_) { |
| 162 base::DictionaryValue* last = new base::DictionaryValue(); |
| 163 last->SetInteger("start_time", (now - last_upload_start_time_).InSeconds()); |
| 164 last->SetInteger("end_time", (now - last_upload_end_time_).InSeconds()); |
| 165 last->SetInteger("collector_index", last_upload_collector_index_); |
| 166 last->SetBoolean("success", last_upload_success_); |
| 167 data->Set("last_upload", last); |
| 168 } |
| 169 |
| 170 base::ListValue* collectors = new base::ListValue(); |
| 171 for (size_t i = 0; i < collectors_.size(); ++i) { |
| 172 const CollectorState* state = &collectors_[i]; |
| 173 base::DictionaryValue* value = new base::DictionaryValue(); |
| 174 value->SetInteger("failures", state->failures); |
| 175 value->SetInteger("next_upload", (state->next_upload - now).InSeconds()); |
| 176 collectors->Append(value); |
| 177 } |
| 178 data->Set("collectors", collectors); |
| 179 |
| 180 return data; |
| 181 } |
| 182 |
137 DomainReliabilityScheduler::CollectorState::CollectorState() : failures(0) {} | 183 DomainReliabilityScheduler::CollectorState::CollectorState() : failures(0) {} |
138 | 184 |
139 void DomainReliabilityScheduler::MaybeScheduleUpload() { | 185 void DomainReliabilityScheduler::MaybeScheduleUpload() { |
140 if (!upload_pending_ || upload_scheduled_ || upload_running_) | 186 if (!upload_pending_ || upload_scheduled_ || upload_running_) |
141 return; | 187 return; |
142 | 188 |
143 upload_scheduled_ = true; | 189 upload_scheduled_ = true; |
144 old_first_beacon_time_ = first_beacon_time_; | 190 old_first_beacon_time_ = first_beacon_time_; |
145 | 191 |
146 base::TimeTicks now = time_->NowTicks(); | 192 base::TimeTicks now = time_->NowTicks(); |
147 | 193 |
148 base::TimeTicks min_by_deadline, max_by_deadline; | 194 base::TimeTicks min_by_deadline, max_by_deadline; |
149 min_by_deadline = first_beacon_time_ + params_.minimum_upload_delay; | 195 min_by_deadline = first_beacon_time_ + params_.minimum_upload_delay; |
150 max_by_deadline = first_beacon_time_ + params_.maximum_upload_delay; | 196 max_by_deadline = first_beacon_time_ + params_.maximum_upload_delay; |
151 DCHECK(min_by_deadline <= max_by_deadline); | 197 DCHECK(min_by_deadline <= max_by_deadline); |
152 | 198 |
153 base::TimeTicks min_by_backoff; | 199 base::TimeTicks min_by_backoff; |
154 size_t collector_index; | 200 size_t collector_index; |
155 GetNextUploadTimeAndCollector(now, &min_by_backoff, &collector_index); | 201 GetNextUploadTimeAndCollector(now, &min_by_backoff, &collector_index); |
156 | 202 |
157 base::TimeDelta min_delay = std::max(min_by_deadline, min_by_backoff) - now; | 203 scheduled_min_time_ = std::max(min_by_deadline, min_by_backoff); |
158 base::TimeDelta max_delay = std::max(max_by_deadline, min_by_backoff) - now; | 204 scheduled_max_time_ = std::max(max_by_deadline, min_by_backoff); |
| 205 |
| 206 base::TimeDelta min_delay = scheduled_min_time_ - now; |
| 207 base::TimeDelta max_delay = scheduled_max_time_ - now; |
159 | 208 |
160 VLOG(1) << "Scheduling upload for between " << min_delay.InSeconds() | 209 VLOG(1) << "Scheduling upload for between " << min_delay.InSeconds() |
161 << " and " << max_delay.InSeconds() << " seconds from now."; | 210 << " and " << max_delay.InSeconds() << " seconds from now."; |
162 | 211 |
163 callback_.Run(min_delay, max_delay); | 212 callback_.Run(min_delay, max_delay); |
164 } | 213 } |
165 | 214 |
166 // TODO(ttuttle): Add min and max interval to config, use that instead. | 215 // TODO(ttuttle): Add min and max interval to config, use that instead. |
167 | 216 |
168 // TODO(ttuttle): Cap min and max intervals received from config. | 217 // TODO(ttuttle): Cap min and max intervals received from config. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 return base::TimeDelta::FromSeconds(0); | 252 return base::TimeDelta::FromSeconds(0); |
204 else { | 253 else { |
205 // Don't back off more than 64x the original delay. | 254 // Don't back off more than 64x the original delay. |
206 if (failures > 7) | 255 if (failures > 7) |
207 failures = 7; | 256 failures = 7; |
208 return params_.upload_retry_interval * (1 << (failures - 1)); | 257 return params_.upload_retry_interval * (1 << (failures - 1)); |
209 } | 258 } |
210 } | 259 } |
211 | 260 |
212 } // namespace domain_reliability | 261 } // namespace domain_reliability |
OLD | NEW |