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

Unified Diff: chrome/browser/sync/profile_sync_service.cc

Issue 62423002: Fix one case that can make sync backend stuck in auth error state. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sync/engine/net/server_connection_manager.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/sync/profile_sync_service.cc
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index f2e0c4ef1a5cbf2307dee27db9641accbb63b4dc..51ee9aef21dc7194439f03cf04201aaa4990a5d0 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -646,8 +646,6 @@ void ProfileSyncService::OnGetTokenSuccess(
const base::Time& expiration_time) {
DCHECK_EQ(access_token_request_, request);
access_token_request_.reset();
- // Reset backoff time after successful response.
- request_access_token_backoff_.Reset();
access_token_ = access_token;
if (sync_prefs_.SyncHasAuthError()) {
@@ -1130,9 +1128,51 @@ void ProfileSyncService::OnConnectionStatusChange(
// Sync server returned error indicating that access token is invalid. It
// could be either expired or access is revoked. Let's request another
// access token and if access is revoked then request for token will fail
- // with corresponding error.
- RequestAccessToken();
+ // with corresponding error. If access token is repeatedly reported
+ // invalid, there may be some issues with server, e.g. authentication
+ // state is inconsistent on sync and token server. In that case, we
+ // backoff token requests exponentially to avoid hammering token server
+ // too much and to avoid getting same token due to token server's caching
+ // policy. |request_access_token_retry_timer_| is used to backoff request
+ // triggered by both auth error and failure talking to GAIA server.
+ // Therefore, we're likely to reach the backoff ceiling more quickly than
+ // you would expect from looking at the BackoffPolicy if both types of
+ // errors happen. We shouldn't receive two errors back-to-back without
+ // attempting a token/sync request in between, thus crank up request delay
+ // unnecessary. This is because we won't make a sync request if we hit an
+ // error until GAIA succeeds at sending a new token, and we won't request
+ // a new token unless sync reports a token failure. But to be safe, don't
+ // schedule request if this happens.
+ if (request_access_token_retry_timer_.IsRunning()) {
+ NOTREACHED();
+ } else if (request_access_token_backoff_.failure_count() == 0) {
+ // First time request without delay. Currently invalid token is used
+ // to initialize sync backend and we'll always end up here. We don't
+ // want to delay initialization.
+ request_access_token_backoff_.InformOfRequest(false);
+ RequestAccessToken();
+ } else {
+ request_access_token_backoff_.InformOfRequest(false);
+ request_access_token_retry_timer_.Start(
+ FROM_HERE,
+ request_access_token_backoff_.GetTimeUntilRelease(),
+ base::Bind(&ProfileSyncService::RequestAccessToken,
+ weak_factory_.GetWeakPtr()));
+ }
} else {
+ // Reset backoff time after successful connection.
+ if (status == syncer::CONNECTION_OK) {
+ // Request shouldn't be scheduled at this time. But if it is, it's
+ // possible that sync flips between OK and auth error states rapidly,
+ // thus hammers token server. To be safe, only reset backoff delay when
+ // no scheduled request.
+ if (request_access_token_retry_timer_.IsRunning()) {
+ NOTREACHED();
+ } else {
+ request_access_token_backoff_.Reset();
+ }
+ }
+
const GoogleServiceAuthError auth_error =
ConnectionStatusToAuthError(status);
DVLOG(1) << "Connection status change: " << auth_error.ToString();
« no previous file with comments | « no previous file | sync/engine/net/server_connection_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698