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

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

Issue 2481873002: Added ClientEvent proto and structure for storing events in the factory. (Closed)
Patch Set: Created 4 years, 1 month 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 <string> 7 #include <string>
8 8
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 27 matching lines...) Expand all
38 38
39 // Decides whether the last login was within kConnectionResetWindowSecs of now 39 // Decides whether the last login was within kConnectionResetWindowSecs of now
40 // or not. 40 // or not.
41 bool ShouldRestorePreviousBackoff(const base::TimeTicks& login_time, 41 bool ShouldRestorePreviousBackoff(const base::TimeTicks& login_time,
42 const base::TimeTicks& now_ticks) { 42 const base::TimeTicks& now_ticks) {
43 return !login_time.is_null() && 43 return !login_time.is_null() &&
44 now_ticks - login_time <= 44 now_ticks - login_time <=
45 base::TimeDelta::FromSeconds(kConnectionResetWindowSecs); 45 base::TimeDelta::FromSeconds(kConnectionResetWindowSecs);
46 } 46 }
47 47
48 const int kMaxClientEvents = 30;
Peter Beverloo 2016/11/28 15:05:15 ++docs. Explain what it is and how this number was
harkness 2016/12/01 10:34:34 Done.
49
48 } // namespace 50 } // namespace
49 51
50 ConnectionFactoryImpl::ConnectionFactoryImpl( 52 ConnectionFactoryImpl::ConnectionFactoryImpl(
51 const std::vector<GURL>& mcs_endpoints, 53 const std::vector<GURL>& mcs_endpoints,
52 const net::BackoffEntry::Policy& backoff_policy, 54 const net::BackoffEntry::Policy& backoff_policy,
53 net::HttpNetworkSession* gcm_network_session, 55 net::HttpNetworkSession* gcm_network_session,
54 net::HttpNetworkSession* http_network_session, 56 net::HttpNetworkSession* http_network_session,
55 net::NetLog* net_log, 57 net::NetLog* net_log,
56 GCMStatsRecorder* recorder) 58 GCMStatsRecorder* recorder)
57 : mcs_endpoints_(mcs_endpoints), 59 : mcs_endpoints_(mcs_endpoints),
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 if (!last_login_time_.is_null()) { 200 if (!last_login_time_.is_null()) {
199 UMA_HISTOGRAM_CUSTOM_TIMES("GCM.ConnectionUpTime", 201 UMA_HISTOGRAM_CUSTOM_TIMES("GCM.ConnectionUpTime",
200 NowTicks() - last_login_time_, 202 NowTicks() - last_login_time_,
201 base::TimeDelta::FromSeconds(1), 203 base::TimeDelta::FromSeconds(1),
202 base::TimeDelta::FromHours(24), 204 base::TimeDelta::FromHours(24),
203 50); 205 50);
204 // |last_login_time_| will be reset below, before attempting the new 206 // |last_login_time_| will be reset below, before attempting the new
205 // connection. 207 // connection.
206 } 208 }
207 209
210 // Record that the connection has ended.
211 if (logging_in_) {
212 // If this was a login failure, the connection established time would have
213 // been set and it would have marked a successful connection, so explicitly
214 // clear that.
215 current_event_.set_type(mcs_proto::ClientEvent::FAILED_CONNECTION);
216 current_event_.clear_time_connection_established_ms();
217 // TODO(harkness): What error code do we want to set?
218 }
219 current_event_.set_time_connection_ended_ms(NowTicks().ToInternalValue());
Peter Beverloo 2016/11/28 15:05:14 Here and elsewhere: I'm not comfortable using ToI
harkness 2016/12/01 10:34:34 Sure, that seems reasonable.
220
208 CloseSocket(); 221 CloseSocket();
209 DCHECK(!IsEndpointReachable()); 222 DCHECK(!IsEndpointReachable());
210 223
211 // TODO(zea): if the network is offline, don't attempt to connect. 224 // TODO(zea): if the network is offline, don't attempt to connect.
212 // See crbug.com/396687 225 // See crbug.com/396687
213 226
214 // Network changes get special treatment as they can trigger a one-off canary 227 // Network changes get special treatment as they can trigger a one-off canary
215 // request that bypasses backoff (but does nothing if a connection is in 228 // request that bypasses backoff (but does nothing if a connection is in
216 // progress). Other connection reset events can be ignored as a connection 229 // progress). Other connection reset events can be ignored as a connection
217 // is already awaiting backoff expiration. 230 // is already awaiting backoff expiration.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 } 266 }
254 267
255 base::TimeTicks ConnectionFactoryImpl::NextRetryAttempt() const { 268 base::TimeTicks ConnectionFactoryImpl::NextRetryAttempt() const {
256 if (!backoff_entry_) 269 if (!backoff_entry_)
257 return base::TimeTicks(); 270 return base::TimeTicks();
258 return backoff_entry_->GetReleaseTime(); 271 return backoff_entry_->GetReleaseTime();
259 } 272 }
260 273
261 void ConnectionFactoryImpl::OnNetworkChanged( 274 void ConnectionFactoryImpl::OnNetworkChanged(
262 net::NetworkChangeNotifier::ConnectionType type) { 275 net::NetworkChangeNotifier::ConnectionType type) {
276 // Record the current network type.
277 network_type_ = type;
Peter Beverloo 2016/11/28 15:05:15 Since we only fire OnNetworkChanged() when it actu
harkness 2016/12/01 10:34:34 You're right, that is going to be a problem. I hav
278
263 if (type == net::NetworkChangeNotifier::CONNECTION_NONE) { 279 if (type == net::NetworkChangeNotifier::CONNECTION_NONE) {
264 DVLOG(1) << "Network lost, resettion connection."; 280 DVLOG(1) << "Network lost, resettion connection.";
265 waiting_for_network_online_ = true; 281 waiting_for_network_online_ = true;
266 282
267 // Will do nothing due to |waiting_for_network_online_ == true|. 283 // Will do nothing due to |waiting_for_network_online_ == true|.
268 // TODO(zea): make the above statement actually true. See crbug.com/396687 284 // TODO(zea): make the above statement actually true. See crbug.com/396687
269 SignalConnectionReset(NETWORK_CHANGE); 285 SignalConnectionReset(NETWORK_CHANGE);
270 return; 286 return;
271 } 287 }
272 288
(...skipping 16 matching lines...) Expand all
289 305
290 net::IPEndPoint ip_endpoint; 306 net::IPEndPoint ip_endpoint;
291 int result = socket_handle_.socket()->GetPeerAddress(&ip_endpoint); 307 int result = socket_handle_.socket()->GetPeerAddress(&ip_endpoint);
292 if (result != net::OK) 308 if (result != net::OK)
293 return net::IPEndPoint(); 309 return net::IPEndPoint();
294 310
295 return ip_endpoint; 311 return ip_endpoint;
296 } 312 }
297 313
298 void ConnectionFactoryImpl::ConnectImpl() { 314 void ConnectionFactoryImpl::ConnectImpl() {
315 if (total_client_events_ >= 0) {
Peter Beverloo 2016/11/28 15:05:15 Instead of having |total_client_events_|, I think
harkness 2016/12/01 10:34:34 Refactored this into the ClientEventTracker, which
316 // If starting a new connection, the previous connection is completed, so
317 // move
318 // the current client event onto the list of past events.
319 mcs_proto::ClientEvent* client_event = nullptr;
320 if (total_client_events_ < kMaxClientEvents) {
321 client_event = client_events_.Add();
322 } else {
323 // If the maximum number of stored events has been exceeded, start
324 // overwriting older entries.
325 client_event =
326 client_events_.Mutable(total_client_events_ % kMaxClientEvents);
327 }
328 client_event->CopyFrom(current_event_);
329 current_event_.Clear();
Peter Beverloo 2016/11/28 15:05:15 it seems to me like this code would become *a lot*
harkness 2016/12/01 10:34:34 Done.
330 }
331 total_client_events_++;
332
333 current_event_.set_time_connection_started_ms(NowTicks().ToInternalValue());
334 current_event_.set_network_type(network_type_);
335
336 StartConnection();
337 }
338
339 void ConnectionFactoryImpl::StartConnection() {
299 DCHECK(!IsEndpointReachable()); 340 DCHECK(!IsEndpointReachable());
300 // TODO(zea): Make this a dcheck again. crbug.com/462319 341 // TODO(zea): Make this a dcheck again. crbug.com/462319
301 CHECK(!socket_handle_.socket()); 342 CHECK(!socket_handle_.socket());
302 343
303 // TODO(zea): if the network is offline, don't attempt to connect. 344 // TODO(zea): if the network is offline, don't attempt to connect.
304 // See crbug.com/396687 345 // See crbug.com/396687
305 346
306 connecting_ = true; 347 connecting_ = true;
307 GURL current_endpoint = GetCurrentEndpoint(); 348 GURL current_endpoint = GetCurrentEndpoint();
308 recorder_->RecordConnectionInitiated(current_endpoint.host()); 349 recorder_->RecordConnectionInitiated(current_endpoint.host());
309 RebuildNetworkSessionAuthCache(); 350 RebuildNetworkSessionAuthCache();
310 int status = gcm_network_session_->proxy_service()->ResolveProxy( 351 int status = gcm_network_session_->proxy_service()->ResolveProxy(
311 current_endpoint, 352 current_endpoint,
312 std::string(), 353 std::string(),
313 &proxy_info_, 354 &proxy_info_,
314 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone, 355 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone,
315 weak_ptr_factory_.GetWeakPtr()), 356 weak_ptr_factory_.GetWeakPtr()),
316 &pac_request_, 357 &pac_request_,
317 NULL, 358 NULL,
318 net_log_); 359 net_log_);
319 if (status != net::ERR_IO_PENDING) 360 if (status != net::ERR_IO_PENDING)
320 OnProxyResolveDone(status); 361 OnProxyResolveDone(status);
321 } 362 }
322 363
323 void ConnectionFactoryImpl::InitHandler() { 364 void ConnectionFactoryImpl::InitHandler() {
324 // May be null in tests. 365 // May be null in tests.
325 mcs_proto::LoginRequest login_request; 366 mcs_proto::LoginRequest login_request;
326 if (!request_builder_.is_null()) { 367 if (!request_builder_.is_null()) {
368 // TODO(harkness): Pass the previous ClientEvents into the request builder.
Peter Beverloo 2016/11/28 15:05:15 This also needs to build a ClientEvent for DISCARD
harkness 2016/12/01 10:34:34 TODO added.
327 request_builder_.Run(&login_request); 369 request_builder_.Run(&login_request);
328 DCHECK(login_request.IsInitialized()); 370 DCHECK(login_request.IsInitialized());
329 } 371 }
330 372
331 connection_handler_->Init(login_request, socket_handle_.socket()); 373 connection_handler_->Init(login_request, socket_handle_.socket());
332 } 374 }
333 375
334 std::unique_ptr<net::BackoffEntry> ConnectionFactoryImpl::CreateBackoffEntry( 376 std::unique_ptr<net::BackoffEntry> ConnectionFactoryImpl::CreateBackoffEntry(
335 const net::BackoffEntry::Policy* const policy) { 377 const net::BackoffEntry::Policy* const policy) {
336 return std::unique_ptr<net::BackoffEntry>(new net::BackoffEntry(policy)); 378 return std::unique_ptr<net::BackoffEntry>(new net::BackoffEntry(policy));
(...skipping 27 matching lines...) Expand all
364 DCHECK_NE(result, net::OK); 406 DCHECK_NE(result, net::OK);
365 if (result == net::ERR_IO_PENDING) 407 if (result == net::ERR_IO_PENDING)
366 return; // Proxy reconsideration pending. Return. 408 return; // Proxy reconsideration pending. Return.
367 LOG(ERROR) << "Failed to connect to MCS endpoint with error " << result; 409 LOG(ERROR) << "Failed to connect to MCS endpoint with error " << result;
368 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", false); 410 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", false);
369 recorder_->RecordConnectionFailure(result); 411 recorder_->RecordConnectionFailure(result);
370 CloseSocket(); 412 CloseSocket();
371 backoff_entry_->InformOfRequest(false); 413 backoff_entry_->InformOfRequest(false);
372 UMA_HISTOGRAM_SPARSE_SLOWLY("GCM.ConnectionFailureErrorCode", result); 414 UMA_HISTOGRAM_SPARSE_SLOWLY("GCM.ConnectionFailureErrorCode", result);
373 415
416 // Record the failed connection so information about it can be sent in the
417 // next login request.
418 current_event_.set_type(mcs_proto::ClientEvent::FAILED_CONNECTION);
419 current_event_.set_time_connection_ended_ms(NowTicks().ToInternalValue());
420 current_event_.set_error_code(result);
421
374 // If there are other endpoints available, use the next endpoint on the 422 // If there are other endpoints available, use the next endpoint on the
375 // subsequent retry. 423 // subsequent retry.
376 next_endpoint_++; 424 next_endpoint_++;
377 if (next_endpoint_ >= mcs_endpoints_.size()) 425 if (next_endpoint_ >= mcs_endpoints_.size())
378 next_endpoint_ = 0; 426 next_endpoint_ = 0;
379 connecting_ = false; 427 connecting_ = false;
380 Connect(); 428 Connect();
381 return; 429 return;
382 } 430 }
383 431
(...skipping 28 matching lines...) Expand all
412 460
413 // Handshake complete, reset backoff. If the login failed with an error, 461 // Handshake complete, reset backoff. If the login failed with an error,
414 // the client should invoke SignalConnectionReset(LOGIN_FAILURE), which will 462 // the client should invoke SignalConnectionReset(LOGIN_FAILURE), which will
415 // restore the previous backoff. 463 // restore the previous backoff.
416 DVLOG(1) << "Handshake complete."; 464 DVLOG(1) << "Handshake complete.";
417 last_login_time_ = NowTicks(); 465 last_login_time_ = NowTicks();
418 previous_backoff_.swap(backoff_entry_); 466 previous_backoff_.swap(backoff_entry_);
419 backoff_entry_->Reset(); 467 backoff_entry_->Reset();
420 logging_in_ = false; 468 logging_in_ = false;
421 469
470 // Record the successful connection so information about it can be sent in the
471 // next login request. If there is a login failure, this will need to be
472 // updated to a failed connection.
473 current_event_.set_type(mcs_proto::ClientEvent::SUCCESSFUL_CONNECTION);
474 current_event_.set_time_connection_established_ms(
475 NowTicks().ToInternalValue());
476
477 // A completed connection means that the old client event data has now been
478 // sent to GCM. Delete old data and reinitialize the count.
479 client_events_.Clear();
480 total_client_events_ = 0;
481
422 if (listener_) 482 if (listener_)
423 listener_->OnConnected(GetCurrentEndpoint(), GetPeerIP()); 483 listener_->OnConnected(GetCurrentEndpoint(), GetPeerIP());
424 } 484 }
425 485
426 // This has largely been copied from 486 // This has largely been copied from
427 // HttpStreamFactoryImpl::Job::DoResolveProxyComplete. This should be 487 // HttpStreamFactoryImpl::Job::DoResolveProxyComplete. This should be
428 // refactored into some common place. 488 // refactored into some common place.
429 void ConnectionFactoryImpl::OnProxyResolveDone(int status) { 489 void ConnectionFactoryImpl::OnProxyResolveDone(int status) {
430 pac_request_ = NULL; 490 pac_request_ = NULL;
431 DVLOG(1) << "Proxy resolution status: " << status; 491 DVLOG(1) << "Proxy resolution status: " << status;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 633
574 void ConnectionFactoryImpl::RebuildNetworkSessionAuthCache() { 634 void ConnectionFactoryImpl::RebuildNetworkSessionAuthCache() {
575 if (!http_network_session_ || !http_network_session_->http_auth_cache()) 635 if (!http_network_session_ || !http_network_session_->http_auth_cache())
576 return; 636 return;
577 637
578 gcm_network_session_->http_auth_cache()->UpdateAllFrom( 638 gcm_network_session_->http_auth_cache()->UpdateAllFrom(
579 *http_network_session_->http_auth_cache()); 639 *http_network_session_->http_auth_cache());
580 } 640 }
581 641
582 } // namespace gcm 642 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698