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

Side by Side Diff: chrome/browser/metrics/perf_provider_chromeos.cc

Issue 364913007: metrics: Add random delays to perf collection (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Pass delays as TimeDeltas; Renamed functions; Disable all timers if logged out; Do not collect when… Created 6 years, 5 months 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/metrics/perf_provider_chromeos.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <string> 5 #include <string>
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 // There may be too many session restores to collect a profile each time. Limit 47 // There may be too many session restores to collect a profile each time. Limit
48 // the collection rate by collecting one per 10 restores. Adjust this number as 48 // the collection rate by collecting one per 10 restores. Adjust this number as
49 // needed. 49 // needed.
50 const int kRestoreSessionSamplingFactor = 10; 50 const int kRestoreSessionSamplingFactor = 10;
51 51
52 // This is used to space out session restore collections in the face of several 52 // This is used to space out session restore collections in the face of several
53 // notifications in a short period of time. There should be no less than this 53 // notifications in a short period of time. There should be no less than this
54 // much time between collections. The current value is 30 seconds. 54 // much time between collections. The current value is 30 seconds.
55 const int kMinIntervalBetweenSessionRestoreCollectionsMs = 30 * 1000; 55 const int kMinIntervalBetweenSessionRestoreCollectionsMs = 30 * 1000;
56 56
57 // If collecting after a resume, add a random delay before collecting. The delay
58 // should be randomly selected between 0 and this value. Currently the value is
59 // equal to 5 seconds.
60 const int kMaxResumeCollectionDelayMs = 5 * 1000;
61
62 // If collecting after a session restore, add a random delay before collecting.
63 // The delay should be randomly selected between 0 and this value. Currently the
64 // value is equal to 10 seconds.
65 const int kMaxRestoreSessionCollectionDelayMs = 10 * 1000;
66
57 // Enumeration representing success and various failure modes for collecting and 67 // Enumeration representing success and various failure modes for collecting and
58 // sending perf data. 68 // sending perf data.
59 enum GetPerfDataOutcome { 69 enum GetPerfDataOutcome {
60 SUCCESS, 70 SUCCESS,
61 NOT_READY_TO_UPLOAD, 71 NOT_READY_TO_UPLOAD,
62 NOT_READY_TO_COLLECT, 72 NOT_READY_TO_COLLECT,
63 INCOGNITO_ACTIVE, 73 INCOGNITO_ACTIVE,
64 INCOGNITO_LAUNCHED, 74 INCOGNITO_LAUNCHED,
65 PROTOBUF_NOT_PARSED, 75 PROTOBUF_NOT_PARSED,
66 NUM_OUTCOMES 76 NUM_OUTCOMES
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 // canceled. Do not collect anything if that's the case. 188 // canceled. Do not collect anything if that's the case.
179 if (sleep_duration == base::TimeDelta()) 189 if (sleep_duration == base::TimeDelta())
180 return; 190 return;
181 191
182 // Do not collect a profile unless logged in. The system behavior when closing 192 // Do not collect a profile unless logged in. The system behavior when closing
183 // the lid or idling when not logged in is currently to shut down instead of 193 // the lid or idling when not logged in is currently to shut down instead of
184 // suspending. But it's good to enforce the rule here in case that changes. 194 // suspending. But it's good to enforce the rule here in case that changes.
185 if (!IsNormalUserLoggedIn()) 195 if (!IsNormalUserLoggedIn())
186 return; 196 return;
187 197
198 // Do not collect if there is an existing collection scheduled.
199 if (resume_timer_.IsRunning())
200 return;
201
188 // Collect a profile only 1/|kResumeSamplingFactor| of the time, to avoid 202 // Collect a profile only 1/|kResumeSamplingFactor| of the time, to avoid
189 // collecting too much data. 203 // collecting too much data.
190 if (base::RandGenerator(kResumeSamplingFactor) != 0) 204 if (base::RandGenerator(kResumeSamplingFactor) != 0)
191 return; 205 return;
192 206
193 // Fill out a SampledProfile protobuf that will contain the collected data. 207 // Randomly pick a delay before doing the collection.
194 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); 208 base::TimeDelta collection_delay =
195 sampled_profile->set_trigger_event(SampledProfile::RESUME_FROM_SUSPEND); 209 base::TimeDelta::FromMilliseconds(
196 sampled_profile->set_suspend_duration_ms(sleep_duration.InMilliseconds()); 210 base::RandGenerator(kMaxResumeCollectionDelayMs));
197 // TODO(sque): Vary the time after resume at which to collect a profile. 211 resume_timer_.Start(FROM_HERE,
198 // http://crbug.com/358778. 212 collection_delay,
199 sampled_profile->set_ms_after_resume(0); 213 base::Bind(&PerfProvider::CollectPerfDataAfterResume,
200 CollectIfNecessary(sampled_profile.Pass()); 214 weak_factory_.GetWeakPtr(),
215 sleep_duration,
216 collection_delay));
Ilya Sherman 2014/07/08 00:06:40 By the way, a timer set to run in 1250ms is not gu
201 } 217 }
202 218
203 void PerfProvider::Observe(int type, 219 void PerfProvider::Observe(int type,
204 const content::NotificationSource& source, 220 const content::NotificationSource& source,
205 const content::NotificationDetails& details) { 221 const content::NotificationDetails& details) {
206 // Only handle session restore notifications. 222 // Only handle session restore notifications.
207 DCHECK_EQ(type, chrome::NOTIFICATION_SESSION_RESTORE_DONE); 223 DCHECK_EQ(type, chrome::NOTIFICATION_SESSION_RESTORE_DONE);
208 224
225 // Do not collect if there is an existing collection scheduled.
226 if (restore_session_timer_.IsRunning())
227 return;
228
229 // Do not collect a profile unless logged in as a normal user.
230 if (!IsNormalUserLoggedIn())
231 return;
232
209 // Collect a profile only 1/|kRestoreSessionSamplingFactor| of the time, to 233 // Collect a profile only 1/|kRestoreSessionSamplingFactor| of the time, to
210 // avoid collecting too much data and potentially causing UI latency. 234 // avoid collecting too much data and potentially causing UI latency.
211 if (base::RandGenerator(kRestoreSessionSamplingFactor) != 0) 235 if (base::RandGenerator(kRestoreSessionSamplingFactor) != 0)
212 return; 236 return;
213 237
214 const base::TimeDelta min_interval = 238 const base::TimeDelta min_interval =
215 base::TimeDelta::FromMilliseconds( 239 base::TimeDelta::FromMilliseconds(
216 kMinIntervalBetweenSessionRestoreCollectionsMs); 240 kMinIntervalBetweenSessionRestoreCollectionsMs);
217 const base::TimeDelta time_since_last_collection = 241 const base::TimeDelta time_since_last_collection =
218 (base::TimeTicks::Now() - last_session_restore_collection_time_); 242 (base::TimeTicks::Now() - last_session_restore_collection_time_);
219 // Do not collect if there hasn't been enough elapsed time since the last 243 // Do not collect if there hasn't been enough elapsed time since the last
220 // collection. 244 // collection.
221 if (!last_session_restore_collection_time_.is_null() && 245 if (!last_session_restore_collection_time_.is_null() &&
222 time_since_last_collection < min_interval) { 246 time_since_last_collection < min_interval) {
223 return; 247 return;
224 } 248 }
225 249
226 // Fill out a SampledProfile protobuf that will contain the collected data. 250 // Randomly pick a delay before doing the collection.
227 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); 251 base::TimeDelta collection_delay =
228 sampled_profile->set_trigger_event(SampledProfile::RESTORE_SESSION); 252 base::TimeDelta::FromMilliseconds(
229 // TODO(sque): Vary the time after restore at which to collect a profile, 253 base::RandGenerator(kMaxRestoreSessionCollectionDelayMs));
230 // and find a way to determine the number of tabs restored. 254 restore_session_timer_.Start(
231 // http://crbug.com/358778. 255 FROM_HERE,
232 sampled_profile->set_ms_after_restore(0); 256 collection_delay,
233 257 base::Bind(&PerfProvider::CollectPerfDataAfterSessionRestore,
234 CollectIfNecessary(sampled_profile.Pass()); 258 weak_factory_.GetWeakPtr(),
235 last_session_restore_collection_time_ = base::TimeTicks::Now(); 259 collection_delay));
236 } 260 }
237 261
238 void PerfProvider::OnUserLoggedIn() { 262 void PerfProvider::OnUserLoggedIn() {
239 login_time_ = base::TimeTicks::Now(); 263 login_time_ = base::TimeTicks::Now();
240 ScheduleCollection(); 264 ScheduleCollection();
241 } 265 }
242 266
243 void PerfProvider::Deactivate() { 267 void PerfProvider::Deactivate() {
244 // Stop the timer, but leave |cached_perf_data_| intact. 268 // Stop the timers, but leave |cached_perf_data_| intact.
245 timer_.Stop(); 269 interval_timer_.Stop();
270 resume_timer_.Stop();
271 restore_session_timer_.Stop();
246 } 272 }
247 273
248 void PerfProvider::ScheduleCollection() { 274 void PerfProvider::ScheduleCollection() {
249 DCHECK(CalledOnValidThread()); 275 DCHECK(CalledOnValidThread());
250 if (timer_.IsRunning()) 276 if (interval_timer_.IsRunning())
251 return; 277 return;
252 278
253 // Pick a random time in the current interval. 279 // Pick a random time in the current interval.
254 base::TimeTicks scheduled_time = 280 base::TimeTicks scheduled_time =
255 next_profiling_interval_start_ + 281 next_profiling_interval_start_ +
256 base::TimeDelta::FromMilliseconds( 282 base::TimeDelta::FromMilliseconds(
257 base::RandGenerator(kPerfProfilingIntervalMs)); 283 base::RandGenerator(kPerfProfilingIntervalMs));
258 284
259 // If the scheduled time has already passed in the time it took to make the 285 // If the scheduled time has already passed in the time it took to make the
260 // above calculations, trigger the collection event immediately. 286 // above calculations, trigger the collection event immediately.
261 base::TimeTicks now = base::TimeTicks::Now(); 287 base::TimeTicks now = base::TimeTicks::Now();
262 if (scheduled_time < now) 288 if (scheduled_time < now)
263 scheduled_time = now; 289 scheduled_time = now;
264 290
265 timer_.Start(FROM_HERE, scheduled_time - now, this, 291 interval_timer_.Start(FROM_HERE, scheduled_time - now, this,
266 &PerfProvider::DoPeriodicCollection); 292 &PerfProvider::DoPeriodicCollection);
267 293
268 // Update the profiling interval tracker to the start of the next interval. 294 // Update the profiling interval tracker to the start of the next interval.
269 next_profiling_interval_start_ += 295 next_profiling_interval_start_ +=
270 base::TimeDelta::FromMilliseconds(kPerfProfilingIntervalMs); 296 base::TimeDelta::FromMilliseconds(kPerfProfilingIntervalMs);
271 } 297 }
272 298
273 void PerfProvider::CollectIfNecessary( 299 void PerfProvider::CollectIfNecessary(
274 scoped_ptr<SampledProfile> sampled_profile) { 300 scoped_ptr<SampledProfile> sampled_profile) {
275 DCHECK(CalledOnValidThread()); 301 DCHECK(CalledOnValidThread());
276 302
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 } 335 }
310 336
311 void PerfProvider::DoPeriodicCollection() { 337 void PerfProvider::DoPeriodicCollection() {
312 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); 338 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile);
313 sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION); 339 sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
314 340
315 CollectIfNecessary(sampled_profile.Pass()); 341 CollectIfNecessary(sampled_profile.Pass());
316 ScheduleCollection(); 342 ScheduleCollection();
317 } 343 }
318 344
345 void PerfProvider::CollectPerfDataAfterResume(
346 const base::TimeDelta& sleep_duration,
347 const base::TimeDelta& time_after_resume) {
348 // Fill out a SampledProfile protobuf that will contain the collected data.
349 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile);
350 sampled_profile->set_trigger_event(SampledProfile::RESUME_FROM_SUSPEND);
351 sampled_profile->set_suspend_duration_ms(sleep_duration.InMilliseconds());
352 sampled_profile->set_ms_after_resume(time_after_resume.InMilliseconds());
353
354 CollectIfNecessary(sampled_profile.Pass());
355 }
356
357 void PerfProvider::CollectPerfDataAfterSessionRestore(
358 const base::TimeDelta& time_after_restore) {
359 // Fill out a SampledProfile protobuf that will contain the collected data.
360 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile);
361 sampled_profile->set_trigger_event(SampledProfile::RESTORE_SESSION);
362 sampled_profile->set_ms_after_restore(time_after_restore.InMilliseconds());
363
364 CollectIfNecessary(sampled_profile.Pass());
365 last_session_restore_collection_time_ = base::TimeTicks::Now();
366 }
367
319 void PerfProvider::ParseProtoIfValid( 368 void PerfProvider::ParseProtoIfValid(
320 scoped_ptr<WindowedIncognitoObserver> incognito_observer, 369 scoped_ptr<WindowedIncognitoObserver> incognito_observer,
321 scoped_ptr<SampledProfile> sampled_profile, 370 scoped_ptr<SampledProfile> sampled_profile,
322 const std::vector<uint8>& data) { 371 const std::vector<uint8>& data) {
323 DCHECK(CalledOnValidThread()); 372 DCHECK(CalledOnValidThread());
324 373
325 if (incognito_observer->incognito_launched()) { 374 if (incognito_observer->incognito_launched()) {
326 AddToPerfHistogram(INCOGNITO_LAUNCHED); 375 AddToPerfHistogram(INCOGNITO_LAUNCHED);
327 return; 376 return;
328 } 377 }
(...skipping 17 matching lines...) Expand all
346 DCHECK(!login_time_.is_null()); 395 DCHECK(!login_time_.is_null());
347 collection_data. 396 collection_data.
348 set_ms_after_login((base::TimeTicks::Now() - login_time_) 397 set_ms_after_login((base::TimeTicks::Now() - login_time_)
349 .InMilliseconds()); 398 .InMilliseconds());
350 399
351 // Finally, store the perf data itself. 400 // Finally, store the perf data itself.
352 collection_data.mutable_perf_data()->Swap(&perf_data_proto); 401 collection_data.mutable_perf_data()->Swap(&perf_data_proto);
353 } 402 }
354 403
355 } // namespace metrics 404 } // namespace metrics
OLDNEW
« no previous file with comments | « chrome/browser/metrics/perf_provider_chromeos.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698