Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 cur_endpoint = GetCurrentEndpoint(); | |
|
jianli
2014/04/23 17:22:35
nit: avoid using abbreviation if possible. so name
juyik
2014/04/23 21:36:56
Done.
| |
| 243 recorder_->RecordConnectionInitiated(cur_endpoint.host()); | |
| 236 int status = network_session_->proxy_service()->ResolveProxy( | 244 int status = network_session_->proxy_service()->ResolveProxy( |
| 237 GetCurrentEndpoint(), | 245 cur_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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 300 connecting_ = false; | 308 connecting_ = false; |
| 301 Connect(); | 309 Connect(); |
| 302 return; | 310 return; |
| 303 } | 311 } |
| 304 | 312 |
| 305 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", true); | 313 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", true); |
| 306 UMA_HISTOGRAM_COUNTS("GCM.ConnectionEndpoint", next_endpoint_); | 314 UMA_HISTOGRAM_COUNTS("GCM.ConnectionEndpoint", next_endpoint_); |
| 307 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectedViaProxy", | 315 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectedViaProxy", |
| 308 !(proxy_info_.is_empty() || proxy_info_.is_direct())); | 316 !(proxy_info_.is_empty() || proxy_info_.is_direct())); |
| 309 ReportSuccessfulProxyConnection(); | 317 ReportSuccessfulProxyConnection(); |
| 318 recorder_->RecordConnectionSuccess(); | |
| 310 | 319 |
| 311 // Reset the endpoint back to the default. | 320 // Reset the endpoint back to the default. |
| 312 // TODO(zea): consider prioritizing endpoints more intelligently based on | 321 // TODO(zea): consider prioritizing endpoints more intelligently based on |
| 313 // which ones succeed most for this client? Although that will affect | 322 // which ones succeed most for this client? Although that will affect |
| 314 // measuring the success rate of the default endpoint vs fallback. | 323 // measuring the success rate of the default endpoint vs fallback. |
| 315 last_successful_endpoint_ = next_endpoint_; | 324 last_successful_endpoint_ = next_endpoint_; |
| 316 next_endpoint_ = 0; | 325 next_endpoint_ = 0; |
| 317 connecting_ = false; | 326 connecting_ = false; |
| 318 logging_in_ = true; | 327 logging_in_ = true; |
| 319 DVLOG(1) << "MCS endpoint socket connection success, starting login."; | 328 DVLOG(1) << "MCS endpoint socket connection success, starting login."; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 483 // the destroyed socket. | 492 // the destroyed socket. |
| 484 if (connection_handler_) | 493 if (connection_handler_) |
| 485 connection_handler_->Reset(); | 494 connection_handler_->Reset(); |
| 486 | 495 |
| 487 if (socket_handle_.socket() && socket_handle_.socket()->IsConnected()) | 496 if (socket_handle_.socket() && socket_handle_.socket()->IsConnected()) |
| 488 socket_handle_.socket()->Disconnect(); | 497 socket_handle_.socket()->Disconnect(); |
| 489 socket_handle_.Reset(); | 498 socket_handle_.Reset(); |
| 490 } | 499 } |
| 491 | 500 |
| 492 } // namespace gcm | 501 } // namespace gcm |
| OLD | NEW |