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

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

Issue 248213004: Record connection, registration, and receiving activities. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 6 years, 7 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/connection_factory_impl.h" 5 #include "google_apis/gcm/engine/connection_factory_impl.h"
6 6
7 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/metrics/sparse_histogram.h" 9 #include "base/metrics/sparse_histogram.h"
10 #include "google_apis/gcm/engine/connection_handler_impl.h" 10 #include "google_apis/gcm/engine/connection_handler_impl.h"
11 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h"
11 #include "google_apis/gcm/protocol/mcs.pb.h" 12 #include "google_apis/gcm/protocol/mcs.pb.h"
12 #include "net/base/net_errors.h" 13 #include "net/base/net_errors.h"
13 #include "net/http/http_network_session.h" 14 #include "net/http/http_network_session.h"
14 #include "net/http/http_request_headers.h" 15 #include "net/http/http_request_headers.h"
15 #include "net/proxy/proxy_info.h" 16 #include "net/proxy/proxy_info.h"
16 #include "net/socket/client_socket_handle.h" 17 #include "net/socket/client_socket_handle.h"
17 #include "net/socket/client_socket_pool_manager.h" 18 #include "net/socket/client_socket_pool_manager.h"
18 #include "net/ssl/ssl_config_service.h" 19 #include "net/ssl/ssl_config_service.h"
19 20
20 namespace gcm { 21 namespace gcm {
(...skipping 16 matching lines...) Expand all
37 now_ticks - login_time <= 38 now_ticks - login_time <=
38 base::TimeDelta::FromSeconds(kConnectionResetWindowSecs); 39 base::TimeDelta::FromSeconds(kConnectionResetWindowSecs);
39 } 40 }
40 41
41 } // namespace 42 } // namespace
42 43
43 ConnectionFactoryImpl::ConnectionFactoryImpl( 44 ConnectionFactoryImpl::ConnectionFactoryImpl(
44 const std::vector<GURL>& mcs_endpoints, 45 const std::vector<GURL>& mcs_endpoints,
45 const net::BackoffEntry::Policy& backoff_policy, 46 const net::BackoffEntry::Policy& backoff_policy,
46 scoped_refptr<net::HttpNetworkSession> network_session, 47 scoped_refptr<net::HttpNetworkSession> network_session,
47 net::NetLog* net_log) 48 net::NetLog* net_log,
49 GCMStatsRecorder* recorder)
48 : mcs_endpoints_(mcs_endpoints), 50 : mcs_endpoints_(mcs_endpoints),
49 next_endpoint_(0), 51 next_endpoint_(0),
50 last_successful_endpoint_(0), 52 last_successful_endpoint_(0),
51 backoff_policy_(backoff_policy), 53 backoff_policy_(backoff_policy),
52 network_session_(network_session), 54 network_session_(network_session),
53 bound_net_log_( 55 bound_net_log_(
54 net::BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)), 56 net::BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)),
55 pac_request_(NULL), 57 pac_request_(NULL),
56 connecting_(false), 58 connecting_(false),
57 waiting_for_backoff_(false), 59 waiting_for_backoff_(false),
58 logging_in_(false), 60 logging_in_(false),
61 recorder_(recorder),
59 weak_ptr_factory_(this) { 62 weak_ptr_factory_(this) {
60 DCHECK_GE(mcs_endpoints_.size(), 1U); 63 DCHECK_GE(mcs_endpoints_.size(), 1U);
61 } 64 }
62 65
63 ConnectionFactoryImpl::~ConnectionFactoryImpl() { 66 ConnectionFactoryImpl::~ConnectionFactoryImpl() {
64 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); 67 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
65 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 68 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
66 if (pac_request_) { 69 if (pac_request_) {
67 network_session_->proxy_service()->CancelPacRequest(pac_request_); 70 network_session_->proxy_service()->CancelPacRequest(pac_request_);
68 pac_request_ = NULL; 71 pac_request_ = NULL;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 if (connecting_ || logging_in_ || IsEndpointReachable()) { 114 if (connecting_ || logging_in_ || IsEndpointReachable()) {
112 waiting_for_backoff_ = false; 115 waiting_for_backoff_ = false;
113 return; 116 return;
114 } 117 }
115 118
116 if (backoff_entry_->ShouldRejectRequest()) { 119 if (backoff_entry_->ShouldRejectRequest()) {
117 DVLOG(1) << "Delaying MCS endpoint connection for " 120 DVLOG(1) << "Delaying MCS endpoint connection for "
118 << backoff_entry_->GetTimeUntilRelease().InMilliseconds() 121 << backoff_entry_->GetTimeUntilRelease().InMilliseconds()
119 << " milliseconds."; 122 << " milliseconds.";
120 waiting_for_backoff_ = true; 123 waiting_for_backoff_ = true;
124 recorder_->RecordConnectionDelayedDueToBackoff(
125 backoff_entry_->GetTimeUntilRelease().InMilliseconds());
121 base::MessageLoop::current()->PostDelayedTask( 126 base::MessageLoop::current()->PostDelayedTask(
122 FROM_HERE, 127 FROM_HERE,
123 base::Bind(&ConnectionFactoryImpl::ConnectWithBackoff, 128 base::Bind(&ConnectionFactoryImpl::ConnectWithBackoff,
124 weak_ptr_factory_.GetWeakPtr()), 129 weak_ptr_factory_.GetWeakPtr()),
125 backoff_entry_->GetTimeUntilRelease()); 130 backoff_entry_->GetTimeUntilRelease());
126 return; 131 return;
127 } 132 }
128 133
129 DVLOG(1) << "Attempting connection to MCS endpoint."; 134 DVLOG(1) << "Attempting connection to MCS endpoint.";
130 waiting_for_backoff_ = false; 135 waiting_for_backoff_ = false;
131 ConnectImpl(); 136 ConnectImpl();
132 } 137 }
133 138
134 bool ConnectionFactoryImpl::IsEndpointReachable() const { 139 bool ConnectionFactoryImpl::IsEndpointReachable() const {
135 return connection_handler_ && connection_handler_->CanSendMessage(); 140 return connection_handler_ && connection_handler_->CanSendMessage();
136 } 141 }
137 142
138 void ConnectionFactoryImpl::SignalConnectionReset( 143 void ConnectionFactoryImpl::SignalConnectionReset(
139 ConnectionResetReason reason) { 144 ConnectionResetReason reason) {
140 // A failure can trigger multiple resets, so no need to do anything if a 145 // A failure can trigger multiple resets, so no need to do anything if a
141 // connection is already in progress. 146 // connection is already in progress.
142 if (connecting_) { 147 if (connecting_) {
143 DVLOG(1) << "Connection in progress, ignoring reset."; 148 DVLOG(1) << "Connection in progress, ignoring reset.";
144 return; 149 return;
145 } 150 }
146 151
147 UMA_HISTOGRAM_ENUMERATION("GCM.ConnectionResetReason", 152 UMA_HISTOGRAM_ENUMERATION("GCM.ConnectionResetReason",
148 reason, 153 reason,
149 CONNECTION_RESET_COUNT); 154 CONNECTION_RESET_COUNT);
155 recorder_->RecordConnectionResetSignaled(reason);
150 if (!last_login_time_.is_null()) { 156 if (!last_login_time_.is_null()) {
151 UMA_HISTOGRAM_CUSTOM_TIMES("GCM.ConnectionUpTime", 157 UMA_HISTOGRAM_CUSTOM_TIMES("GCM.ConnectionUpTime",
152 NowTicks() - last_login_time_, 158 NowTicks() - last_login_time_,
153 base::TimeDelta::FromSeconds(1), 159 base::TimeDelta::FromSeconds(1),
154 base::TimeDelta::FromHours(24), 160 base::TimeDelta::FromHours(24),
155 50); 161 50);
156 // |last_login_time_| will be reset below, before attempting the new 162 // |last_login_time_| will be reset below, before attempting the new
157 // connection. 163 // connection.
158 } 164 }
159 165
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 if (IsEndpointReachable()) 232 if (IsEndpointReachable())
227 return mcs_endpoints_[last_successful_endpoint_]; 233 return mcs_endpoints_[last_successful_endpoint_];
228 return mcs_endpoints_[next_endpoint_]; 234 return mcs_endpoints_[next_endpoint_];
229 } 235 }
230 236
231 void ConnectionFactoryImpl::ConnectImpl() { 237 void ConnectionFactoryImpl::ConnectImpl() {
232 DCHECK(!IsEndpointReachable()); 238 DCHECK(!IsEndpointReachable());
233 DCHECK(!socket_handle_.socket()); 239 DCHECK(!socket_handle_.socket());
234 240
235 connecting_ = true; 241 connecting_ = true;
242 GURL current_endpoint = GetCurrentEndpoint();
243 recorder_->RecordConnectionInitiated(current_endpoint.host());
236 int status = network_session_->proxy_service()->ResolveProxy( 244 int status = network_session_->proxy_service()->ResolveProxy(
237 GetCurrentEndpoint(), 245 current_endpoint,
238 &proxy_info_, 246 &proxy_info_,
239 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone, 247 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone,
240 weak_ptr_factory_.GetWeakPtr()), 248 weak_ptr_factory_.GetWeakPtr()),
241 &pac_request_, 249 &pac_request_,
242 bound_net_log_); 250 bound_net_log_);
243 if (status != net::ERR_IO_PENDING) 251 if (status != net::ERR_IO_PENDING)
244 OnProxyResolveDone(status); 252 OnProxyResolveDone(status);
245 } 253 }
246 254
247 void ConnectionFactoryImpl::InitHandler() { 255 void ConnectionFactoryImpl::InitHandler() {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 // If the connection fails, try another proxy. 289 // If the connection fails, try another proxy.
282 result = ReconsiderProxyAfterError(result); 290 result = ReconsiderProxyAfterError(result);
283 // ReconsiderProxyAfterError either returns an error (in which case it is 291 // ReconsiderProxyAfterError either returns an error (in which case it is
284 // not reconsidering a proxy) or returns ERR_IO_PENDING if it is considering 292 // not reconsidering a proxy) or returns ERR_IO_PENDING if it is considering
285 // another proxy. 293 // another proxy.
286 DCHECK_NE(result, net::OK); 294 DCHECK_NE(result, net::OK);
287 if (result == net::ERR_IO_PENDING) 295 if (result == net::ERR_IO_PENDING)
288 return; // Proxy reconsideration pending. Return. 296 return; // Proxy reconsideration pending. Return.
289 LOG(ERROR) << "Failed to connect to MCS endpoint with error " << result; 297 LOG(ERROR) << "Failed to connect to MCS endpoint with error " << result;
290 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", false); 298 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", false);
299 recorder_->RecordConnectionFailure(result);
291 CloseSocket(); 300 CloseSocket();
292 backoff_entry_->InformOfRequest(false); 301 backoff_entry_->InformOfRequest(false);
293 UMA_HISTOGRAM_SPARSE_SLOWLY("GCM.ConnectionFailureErrorCode", result); 302 UMA_HISTOGRAM_SPARSE_SLOWLY("GCM.ConnectionFailureErrorCode", result);
294 303
295 // If there are other endpoints available, use the next endpoint on the 304 // If there are other endpoints available, use the next endpoint on the
296 // subsequent retry. 305 // subsequent retry.
297 next_endpoint_++; 306 next_endpoint_++;
298 if (next_endpoint_ >= mcs_endpoints_.size()) 307 if (next_endpoint_ >= mcs_endpoints_.size())
299 next_endpoint_ = 0; 308 next_endpoint_ = 0;
300 connecting_ = false; 309 connecting_ = false;
301 Connect(); 310 Connect();
302 return; 311 return;
303 } 312 }
304 313
305 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", true); 314 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", true);
306 UMA_HISTOGRAM_COUNTS("GCM.ConnectionEndpoint", next_endpoint_); 315 UMA_HISTOGRAM_COUNTS("GCM.ConnectionEndpoint", next_endpoint_);
307 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectedViaProxy", 316 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectedViaProxy",
308 !(proxy_info_.is_empty() || proxy_info_.is_direct())); 317 !(proxy_info_.is_empty() || proxy_info_.is_direct()));
309 ReportSuccessfulProxyConnection(); 318 ReportSuccessfulProxyConnection();
319 recorder_->RecordConnectionSuccess();
310 320
311 // Reset the endpoint back to the default. 321 // Reset the endpoint back to the default.
312 // TODO(zea): consider prioritizing endpoints more intelligently based on 322 // TODO(zea): consider prioritizing endpoints more intelligently based on
313 // which ones succeed most for this client? Although that will affect 323 // which ones succeed most for this client? Although that will affect
314 // measuring the success rate of the default endpoint vs fallback. 324 // measuring the success rate of the default endpoint vs fallback.
315 last_successful_endpoint_ = next_endpoint_; 325 last_successful_endpoint_ = next_endpoint_;
316 next_endpoint_ = 0; 326 next_endpoint_ = 0;
317 connecting_ = false; 327 connecting_ = false;
318 logging_in_ = true; 328 logging_in_ = true;
319 DVLOG(1) << "MCS endpoint socket connection success, starting login."; 329 DVLOG(1) << "MCS endpoint socket connection success, starting login.";
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 // the destroyed socket. 493 // the destroyed socket.
484 if (connection_handler_) 494 if (connection_handler_)
485 connection_handler_->Reset(); 495 connection_handler_->Reset();
486 496
487 if (socket_handle_.socket() && socket_handle_.socket()->IsConnected()) 497 if (socket_handle_.socket() && socket_handle_.socket()->IsConnected())
488 socket_handle_.socket()->Disconnect(); 498 socket_handle_.socket()->Disconnect();
489 socket_handle_.Reset(); 499 socket_handle_.Reset();
490 } 500 }
491 501
492 } // namespace gcm 502 } // namespace gcm
OLDNEW
« no previous file with comments | « google_apis/gcm/engine/connection_factory_impl.h ('k') | google_apis/gcm/engine/connection_factory_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698