- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / metrics / metrics_reporting_scheduler.cc
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/metrics/metrics_reporting_scheduler.h"
6
7 #include "base/compiler_specific.h"
8 #include "chrome/browser/metrics/metrics_service.h"
9
10 using base::TimeDelta;
11
12 namespace {
13
14 // The delay, in seconds, after startup before sending the first log message.
15 #if defined(OS_ANDROID) || defined(OS_IOS)
16 // Sessions are more likely to be short on a mobile device, so handle the
17 // initial log quickly.
18 const int kInitialUploadIntervalSeconds = 15;
19 #else
20 const int kInitialUploadIntervalSeconds = 60;
21 #endif
22
23 // The delay, in seconds, between uploading when there are queued logs from
24 // previous sessions to send.
25 #if defined(OS_ANDROID) || defined(OS_IOS)
26 // Sending in a burst is better on a mobile device, since keeping the radio on
27 // is very expensive.
28 const int kUnsentLogsIntervalSeconds = 3;
29 #else
30 const int kUnsentLogsIntervalSeconds = 15;
31 #endif
32
33 // Standard interval between log uploads, in seconds.
34 #if defined(OS_ANDROID) || defined(OS_IOS)
35 const int kStandardUploadIntervalSeconds = 5 * 60;  // Five minutes.
36 #else
37 const int kStandardUploadIntervalSeconds = 30 * 60;  // Thirty minutes.
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     : upload_callback_(upload_callback),
54       upload_interval_(TimeDelta::FromSeconds(kInitialUploadIntervalSeconds)),
55       running_(false),
56       callback_pending_(false) {
57 }
58
59 MetricsReportingScheduler::~MetricsReportingScheduler() {}
60
61 void MetricsReportingScheduler::Start() {
62   running_ = true;
63   ScheduleNextUpload();
64 }
65
66 void MetricsReportingScheduler::Stop() {
67   running_ = false;
68   if (upload_timer_.IsRunning())
69     upload_timer_.Stop();
70 }
71
72 void MetricsReportingScheduler::UploadFinished(bool server_is_healthy,
73                                                bool more_logs_remaining) {
74   DCHECK(callback_pending_);
75   callback_pending_ = false;
76   // If the server is having issues, back off. Otherwise, reset to default
77   // (unless there are more logs to send, in which case the next upload should
78   // happen sooner).
79   if (!server_is_healthy) {
80     BackOffUploadInterval();
81   } else if (more_logs_remaining) {
82     upload_interval_ = TimeDelta::FromSeconds(kUnsentLogsIntervalSeconds);
83   } else {
84     upload_interval_ = TimeDelta::FromSeconds(kStandardUploadIntervalSeconds);
85   }
86
87   if (running_)
88     ScheduleNextUpload();
89 }
90
91 void MetricsReportingScheduler::UploadCancelled() {
92   DCHECK(callback_pending_);
93   callback_pending_ = false;
94   if (running_)
95     ScheduleNextUpload();
96 }
97
98 void MetricsReportingScheduler::TriggerUpload() {
99   callback_pending_ = true;
100   upload_callback_.Run();
101 }
102
103 void MetricsReportingScheduler::ScheduleNextUpload() {
104   DCHECK(running_);
105   if (upload_timer_.IsRunning() || callback_pending_)
106     return;
107
108   upload_timer_.Start(FROM_HERE, upload_interval_, this,
109                       &MetricsReportingScheduler::TriggerUpload);
110 }
111
112 void MetricsReportingScheduler::BackOffUploadInterval() {
113   DCHECK_GT(kBackoffMultiplier, 1.0);
114   upload_interval_ = TimeDelta::FromMicroseconds(
115       static_cast<int64>(kBackoffMultiplier *
116                          upload_interval_.InMicroseconds()));
117
118   TimeDelta max_interval = kMaxBackoffMultiplier *
119       TimeDelta::FromSeconds(kStandardUploadIntervalSeconds);
120   if (upload_interval_ > max_interval || upload_interval_.InSeconds() < 0) {
121     upload_interval_ = max_interval;
122   }
123 }