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

Side by Side Diff: google_apis/gcm/engine/heartbeat_manager.cc

Issue 1758573004: [GCM] Fixing the client interval interaction with heartbeat ack (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressing CR feedback Created 4 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
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 "google_apis/gcm/engine/heartbeat_manager.h" 5 #include "google_apis/gcm/engine/heartbeat_manager.h"
6 6
7 #include <limits>
Nicolas Zea 2016/03/03 19:09:40 nit: not needed anymore
fgorski 2016/03/03 20:31:32 Done.
7 #include <utility> 8 #include <utility>
8 9
9 #include "base/callback.h" 10 #include "base/callback.h"
10 #include "base/location.h" 11 #include "base/location.h"
11 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
12 #include "base/power_monitor/power_monitor.h" 13 #include "base/power_monitor/power_monitor.h"
13 #include "base/thread_task_runner_handle.h" 14 #include "base/thread_task_runner_handle.h"
14 #include "base/time/time.h" 15 #include "base/time/time.h"
15 #include "base/timer/timer.h" 16 #include "base/timer/timer.h"
16 #include "build/build_config.h" 17 #include "build/build_config.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 DCHECK(!send_heartbeat_callback.is_null()); 65 DCHECK(!send_heartbeat_callback.is_null());
65 DCHECK(!trigger_reconnect_callback.is_null()); 66 DCHECK(!trigger_reconnect_callback.is_null());
66 send_heartbeat_callback_ = send_heartbeat_callback; 67 send_heartbeat_callback_ = send_heartbeat_callback;
67 trigger_reconnect_callback_ = trigger_reconnect_callback; 68 trigger_reconnect_callback_ = trigger_reconnect_callback;
68 69
69 // Listen for system suspend and resume events. 70 // Listen for system suspend and resume events.
70 base::PowerMonitor* monitor = base::PowerMonitor::Get(); 71 base::PowerMonitor* monitor = base::PowerMonitor::Get();
71 if (monitor) 72 if (monitor)
72 monitor->AddObserver(this); 73 monitor->AddObserver(this);
73 74
75 // Calculated the heartbeat interval just before we start the timer.
76 UpdateHeartbeatInterval();
77
74 // Kicks off the timer. 78 // Kicks off the timer.
75 waiting_for_ack_ = false; 79 waiting_for_ack_ = false;
76 RestartTimer(); 80 RestartTimer();
77 } 81 }
78 82
79 void HeartbeatManager::Stop() { 83 void HeartbeatManager::Stop() {
80 heartbeat_expected_time_ = base::Time(); 84 heartbeat_expected_time_ = base::Time();
81 heartbeat_interval_ms_ = 0; 85 heartbeat_interval_ms_ = 0;
82 heartbeat_timer_->Stop(); 86 heartbeat_timer_->Stop();
83 waiting_for_ack_ = false; 87 waiting_for_ack_ = false;
(...skipping 15 matching lines...) Expand all
99 103
100 void HeartbeatManager::UpdateHeartbeatConfig( 104 void HeartbeatManager::UpdateHeartbeatConfig(
101 const mcs_proto::HeartbeatConfig& config) { 105 const mcs_proto::HeartbeatConfig& config) {
102 if (!config.IsInitialized() || 106 if (!config.IsInitialized() ||
103 !config.has_interval_ms() || 107 !config.has_interval_ms() ||
104 config.interval_ms() <= 0) { 108 config.interval_ms() <= 0) {
105 return; 109 return;
106 } 110 }
107 DVLOG(1) << "Updating server heartbeat interval to " << config.interval_ms(); 111 DVLOG(1) << "Updating server heartbeat interval to " << config.interval_ms();
108 server_interval_ms_ = config.interval_ms(); 112 server_interval_ms_ = config.interval_ms();
113
114 // Make sure heartbeat interval is recalculated when new server interval is
115 // available.
116 UpdateHeartbeatInterval();
109 } 117 }
110 118
111 base::TimeTicks HeartbeatManager::GetNextHeartbeatTime() const { 119 base::TimeTicks HeartbeatManager::GetNextHeartbeatTime() const {
112 if (heartbeat_timer_->IsRunning()) 120 if (heartbeat_timer_->IsRunning())
113 return heartbeat_timer_->desired_run_time(); 121 return heartbeat_timer_->desired_run_time();
114 else 122 else
115 return base::TimeTicks(); 123 return base::TimeTicks();
116 } 124 }
117 125
118 void HeartbeatManager::UpdateHeartbeatTimer(scoped_ptr<base::Timer> timer) { 126 void HeartbeatManager::UpdateHeartbeatTimer(scoped_ptr<base::Timer> timer) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 ResetConnection(ConnectionFactory::HEARTBEAT_FAILURE); 167 ResetConnection(ConnectionFactory::HEARTBEAT_FAILURE);
160 return; 168 return;
161 } 169 }
162 170
163 waiting_for_ack_ = true; 171 waiting_for_ack_ = true;
164 RestartTimer(); 172 RestartTimer();
165 send_heartbeat_callback_.Run(); 173 send_heartbeat_callback_.Run();
166 } 174 }
167 175
168 void HeartbeatManager::RestartTimer() { 176 void HeartbeatManager::RestartTimer() {
177 int interval_ms = heartbeat_interval_ms_;
169 if (!waiting_for_ack_) { 178 if (!waiting_for_ack_) {
Nicolas Zea 2016/03/03 19:09:40 nit: for readability, would be better to do: if (w
fgorski 2016/03/03 20:31:32 Done.
170 // Recalculate the timer interval based network type. 179 DVLOG(1) << "Sending next heartbeat in " << interval_ms << " ms.";
171 // Server interval takes precedence over client interval, even if the latter
172 // is less.
173 if (server_interval_ms_ != 0) {
174 // If a server interval is set, it overrides any local one.
175 heartbeat_interval_ms_ = server_interval_ms_;
176 } else if (HasClientHeartbeatInterval()) {
177 // Client interval might have been adjusted up, which should only take
178 // effect during a reconnection.
179 if (client_interval_ms_ < heartbeat_interval_ms_ ||
180 heartbeat_interval_ms_ == 0) {
181 heartbeat_interval_ms_ = client_interval_ms_;
182 }
183 } else {
184 heartbeat_interval_ms_ = GetDefaultHeartbeatInterval();
185 }
186 DVLOG(1) << "Sending next heartbeat in "
187 << heartbeat_interval_ms_ << " ms.";
188 } else { 180 } else {
189 heartbeat_interval_ms_ = kHeartbeatAckDefaultMs; 181 interval_ms = kHeartbeatAckDefaultMs;
190 DVLOG(1) << "Resetting timer for ack with " 182 DVLOG(1) << "Resetting timer for ack within " << interval_ms << " ms.";
191 << heartbeat_interval_ms_ << " ms interval.";
192 } 183 }
193 184
194 heartbeat_expected_time_ = 185 heartbeat_expected_time_ =
195 base::Time::Now() + 186 base::Time::Now() + base::TimeDelta::FromMilliseconds(interval_ms);
196 base::TimeDelta::FromMilliseconds(heartbeat_interval_ms_);
197 heartbeat_timer_->Start(FROM_HERE, 187 heartbeat_timer_->Start(FROM_HERE,
198 base::TimeDelta::FromMilliseconds( 188 base::TimeDelta::FromMilliseconds(interval_ms),
199 heartbeat_interval_ms_), 189 base::Bind(&HeartbeatManager::OnHeartbeatTriggered,
200 base::Bind(&HeartbeatManager::OnHeartbeatTriggered, 190 weak_ptr_factory_.GetWeakPtr()));
201 weak_ptr_factory_.GetWeakPtr()));
202 191
203 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 192 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
204 // Windows, Mac, Android, iOS, and Chrome OS all provide a way to be notified 193 // Windows, Mac, Android, iOS, and Chrome OS all provide a way to be notified
205 // when the system is suspending or resuming. The only one that does not is 194 // when the system is suspending or resuming. The only one that does not is
206 // Linux so we need to poll to check for missed heartbeats. 195 // Linux so we need to poll to check for missed heartbeats.
207 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 196 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
208 FROM_HERE, 197 FROM_HERE,
209 base::Bind(&HeartbeatManager::CheckForMissedHeartbeat, 198 base::Bind(&HeartbeatManager::CheckForMissedHeartbeat,
210 weak_ptr_factory_.GetWeakPtr()), 199 weak_ptr_factory_.GetWeakPtr()),
211 base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs)); 200 base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs));
(...skipping 16 matching lines...) Expand all
228 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 217 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
229 // Otherwise check again later. 218 // Otherwise check again later.
230 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 219 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
231 FROM_HERE, 220 FROM_HERE,
232 base::Bind(&HeartbeatManager::CheckForMissedHeartbeat, 221 base::Bind(&HeartbeatManager::CheckForMissedHeartbeat,
233 weak_ptr_factory_.GetWeakPtr()), 222 weak_ptr_factory_.GetWeakPtr()),
234 base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs)); 223 base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs));
235 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) 224 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS)
236 } 225 }
237 226
227 void HeartbeatManager::UpdateHeartbeatInterval() {
228 // Server interval takes precedence over client interval, even if the latter
229 // is less.
230 if (server_interval_ms_ != 0) {
231 // If a server interval is set, it overrides any local one.
232 heartbeat_interval_ms_ = server_interval_ms_;
233 } else if (HasClientHeartbeatInterval() &&
234 (client_interval_ms_ < heartbeat_interval_ms_ ||
235 heartbeat_interval_ms_ == 0)) {
236 // Client interval might have been adjusted up, which should only take
237 // effect during a reconnection.
238 heartbeat_interval_ms_ = client_interval_ms_;
239 } else if (heartbeat_interval_ms_ == 0) {
240 // If interval is still 0, recalculate it based on network type.
241 heartbeat_interval_ms_ = GetDefaultHeartbeatInterval();
242 }
fgorski 2016/03/03 17:10:35 zea@ perhaps we can have a DCHECK(heartbeat_interv
Nicolas Zea 2016/03/03 19:09:40 DCHECK_GT, but yes SGTM :)
243 }
244
238 int HeartbeatManager::GetDefaultHeartbeatInterval() { 245 int HeartbeatManager::GetDefaultHeartbeatInterval() {
239 // For unknown connections, use the longer cellular heartbeat interval. 246 // For unknown connections, use the longer cellular heartbeat interval.
240 int heartbeat_interval_ms = kCellHeartbeatDefaultMs; 247 int heartbeat_interval_ms = kCellHeartbeatDefaultMs;
241 if (net::NetworkChangeNotifier::GetConnectionType() == 248 if (net::NetworkChangeNotifier::GetConnectionType() ==
242 net::NetworkChangeNotifier::CONNECTION_WIFI || 249 net::NetworkChangeNotifier::CONNECTION_WIFI ||
243 net::NetworkChangeNotifier::GetConnectionType() == 250 net::NetworkChangeNotifier::GetConnectionType() ==
244 net::NetworkChangeNotifier::CONNECTION_ETHERNET) { 251 net::NetworkChangeNotifier::CONNECTION_ETHERNET) {
245 heartbeat_interval_ms = kWifiHeartbeatDefaultMs; 252 heartbeat_interval_ms = kWifiHeartbeatDefaultMs;
246 } 253 }
247 return heartbeat_interval_ms; 254 return heartbeat_interval_ms;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 interval <= max_heartbeat_interval; 293 interval <= max_heartbeat_interval;
287 } 294 }
288 295
289 void HeartbeatManager::ResetConnection( 296 void HeartbeatManager::ResetConnection(
290 ConnectionFactory::ConnectionResetReason reason) { 297 ConnectionFactory::ConnectionResetReason reason) {
291 Stop(); 298 Stop();
292 trigger_reconnect_callback_.Run(reason); 299 trigger_reconnect_callback_.Run(reason);
293 } 300 }
294 301
295 } // namespace gcm 302 } // namespace gcm
OLDNEW
« no previous file with comments | « google_apis/gcm/engine/heartbeat_manager.h ('k') | google_apis/gcm/engine/heartbeat_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698