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

Side by Side Diff: components/metrics/metrics_reporting_scheduler.cc

Issue 2770853002: Create Ukm ReportingService implementation. (Closed)
Patch Set: Also revert datatracker unittest change Created 3 years, 9 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "components/metrics/metrics_reporting_scheduler.h"
6
7 #include <stdint.h>
8
9 #include "base/compiler_specific.h"
10 #include "base/metrics/histogram_macros.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "build/build_config.h"
13 #include "components/variations/variations_associated_data.h"
14
15 using base::TimeDelta;
16
17 namespace metrics {
18
19 namespace {
20
21 // The delay, in seconds, after startup before sending the first log message.
22 #if defined(OS_ANDROID) || defined(OS_IOS)
23 // Sessions are more likely to be short on a mobile device, so handle the
24 // initial log quickly.
25 const int kInitialUploadIntervalSeconds = 15;
26 #else
27 const int kInitialUploadIntervalSeconds = 60;
28 #endif
29
30 // The delay, in seconds, between uploading when there are queued logs from
31 // previous sessions to send.
32 #if defined(OS_ANDROID) || defined(OS_IOS)
33 // Sending in a burst is better on a mobile device, since keeping the radio on
34 // is very expensive.
35 const int kUnsentLogsIntervalSeconds = 3;
36 #else
37 const int kUnsentLogsIntervalSeconds = 15;
38 #endif
39
40 // When uploading metrics to the server fails, we progressively wait longer and
41 // longer before sending the next log. This backoff process helps reduce load
42 // on a server that is having issues.
43 // The following is the multiplier we use to expand that inter-log duration.
44 const double kBackoffMultiplier = 1.1;
45
46 // The maximum backoff multiplier.
47 const int kMaxBackoffMultiplier = 10;
48
49 } // anonymous namespace
50
51 MetricsReportingScheduler::MetricsReportingScheduler(
52 const base::Closure& upload_callback,
53 const base::Callback<base::TimeDelta(void)>& upload_interval_callback)
54 : upload_callback_(upload_callback),
55 upload_interval_(TimeDelta::FromSeconds(kInitialUploadIntervalSeconds)),
56 running_(false),
57 callback_pending_(false),
58 init_task_complete_(false),
59 waiting_for_init_task_complete_(false),
60 upload_interval_callback_(upload_interval_callback) {
61 }
62
63 MetricsReportingScheduler::~MetricsReportingScheduler() {}
64
65 void MetricsReportingScheduler::Start() {
66 running_ = true;
67 ScheduleNextUpload();
68 }
69
70 void MetricsReportingScheduler::Stop() {
71 running_ = false;
72 if (upload_timer_.IsRunning())
73 upload_timer_.Stop();
74 }
75
76 // Callback from MetricsService when the startup init task has completed.
77 void MetricsReportingScheduler::InitTaskComplete() {
78 DCHECK(!init_task_complete_);
79 init_task_complete_ = true;
80 if (waiting_for_init_task_complete_) {
81 waiting_for_init_task_complete_ = false;
82 TriggerUpload();
83 } else {
84 LogMetricsInitSequence(INIT_TASK_COMPLETED_FIRST);
85 }
86 }
87
88 void MetricsReportingScheduler::UploadFinished(bool server_is_healthy,
89 bool more_logs_remaining) {
90 DCHECK(callback_pending_);
91 callback_pending_ = false;
92 // If the server is having issues, back off. Otherwise, reset to default
93 // (unless there are more logs to send, in which case the next upload should
94 // happen sooner).
95 if (!server_is_healthy) {
96 BackOffUploadInterval();
97 } else if (more_logs_remaining) {
98 upload_interval_ = TimeDelta::FromSeconds(kUnsentLogsIntervalSeconds);
99 } else {
100 upload_interval_ = GetStandardUploadInterval();
101 last_upload_finish_time_ = base::TimeTicks::Now();
102 }
103
104 if (running_)
105 ScheduleNextUpload();
106 }
107
108 void MetricsReportingScheduler::UploadCancelled() {
109 DCHECK(callback_pending_);
110 callback_pending_ = false;
111 if (running_)
112 ScheduleNextUpload();
113 }
114
115 void MetricsReportingScheduler::SetUploadIntervalForTesting(
116 base::TimeDelta interval) {
117 upload_interval_ = interval;
118 }
119
120 void MetricsReportingScheduler::LogMetricsInitSequence(InitSequence sequence) {
121 UMA_HISTOGRAM_ENUMERATION("UMA.InitSequence", sequence,
122 INIT_SEQUENCE_ENUM_SIZE);
123 }
124
125 void MetricsReportingScheduler::LogActualUploadInterval(TimeDelta interval) {
126 UMA_HISTOGRAM_CUSTOM_COUNTS("UMA.ActualLogUploadInterval",
127 interval.InMinutes(),
128 1,
129 base::TimeDelta::FromHours(12).InMinutes(),
130 50);
131 }
132
133 void MetricsReportingScheduler::TriggerUpload() {
134 // If the timer fired before the init task has completed, don't trigger the
135 // upload yet - wait for the init task to complete and do it then.
136 if (!init_task_complete_) {
137 LogMetricsInitSequence(TIMER_FIRED_FIRST);
138 waiting_for_init_task_complete_ = true;
139 return;
140 }
141
142 if (!last_upload_finish_time_.is_null()) {
143 LogActualUploadInterval(base::TimeTicks::Now() - last_upload_finish_time_);
144 last_upload_finish_time_ = base::TimeTicks();
145 }
146
147 callback_pending_ = true;
148 upload_callback_.Run();
149 }
150
151 void MetricsReportingScheduler::ScheduleNextUpload() {
152 DCHECK(running_);
153 if (upload_timer_.IsRunning() || callback_pending_)
154 return;
155
156 upload_timer_.Start(FROM_HERE, upload_interval_, this,
157 &MetricsReportingScheduler::TriggerUpload);
158 }
159
160 void MetricsReportingScheduler::BackOffUploadInterval() {
161 DCHECK_GT(kBackoffMultiplier, 1.0);
162 upload_interval_ = TimeDelta::FromMicroseconds(static_cast<int64_t>(
163 kBackoffMultiplier * upload_interval_.InMicroseconds()));
164
165 TimeDelta max_interval = kMaxBackoffMultiplier * GetStandardUploadInterval();
166 if (upload_interval_ > max_interval || upload_interval_.InSeconds() < 0) {
167 upload_interval_ = max_interval;
168 }
169 }
170
171 base::TimeDelta MetricsReportingScheduler::GetStandardUploadInterval() {
172 return upload_interval_callback_.Run();
173 }
174
175 } // namespace metrics
OLDNEW
« no previous file with comments | « components/metrics/metrics_reporting_scheduler.h ('k') | components/metrics/metrics_reporting_scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698