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

Side by Side Diff: chrome/browser/chromeos/arc/arc_auth_context.cc

Issue 2896513002: [Merge M59] arg: Implement retry logic for transient errors (Closed)
Patch Set: Created 3 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
« no previous file with comments | « chrome/browser/chromeos/arc/arc_auth_context.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "chrome/browser/chromeos/arc/arc_auth_context.h" 5 #include "chrome/browser/chromeos/arc/arc_auth_context.h"
6 6
7 #include "base/callback_helpers.h" 7 #include "base/callback_helpers.h"
8 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/chromeos/arc/arc_support_host.h" 10 #include "chrome/browser/chromeos/arc/arc_support_host.h"
11 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 12 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
13 #include "chrome/browser/signin/signin_manager_factory.h" 13 #include "chrome/browser/signin/signin_manager_factory.h"
14 #include "chrome/browser/signin/signin_ui_util.h" 14 #include "chrome/browser/signin/signin_ui_util.h"
15 #include "components/signin/core/browser/profile_oauth2_token_service.h" 15 #include "components/signin/core/browser/profile_oauth2_token_service.h"
16 #include "components/signin/core/browser/signin_manager_base.h" 16 #include "components/signin/core/browser/signin_manager_base.h"
17 #include "content/public/browser/browser_context.h" 17 #include "content/public/browser/browser_context.h"
18 #include "content/public/browser/storage_partition.h" 18 #include "content/public/browser/storage_partition.h"
19 #include "content/public/common/url_constants.h" 19 #include "content/public/common/url_constants.h"
20 #include "google_apis/gaia/gaia_auth_fetcher.h" 20 #include "google_apis/gaia/gaia_auth_fetcher.h"
21 #include "google_apis/gaia/gaia_constants.h" 21 #include "google_apis/gaia/gaia_constants.h"
22 22
23 namespace arc { 23 namespace arc {
24 24
25 namespace { 25 namespace {
26 26
27 constexpr int kMaxRetryAttempts = 3;
28
27 constexpr base::TimeDelta kRefreshTokenTimeout = 29 constexpr base::TimeDelta kRefreshTokenTimeout =
28 base::TimeDelta::FromSeconds(10); 30 base::TimeDelta::FromSeconds(10);
29 31
32 constexpr net::BackoffEntry::Policy kRetryBackoffPolicy = {
33 // Number of initial errors (in sequence) to ignore before applying
34 // exponential back-off rules.
35 0,
36
37 // Initial delay for exponential back-off in ms.
38 5000,
39
40 // Factor by which the waiting time will be multiplied.
41 2.0,
42
43 // Fuzzing percentage. ex: 10% will spread requests randomly
44 // between 90%-100% of the calculated time.
45 0.0, // 0%
46
47 // Maximum amount of time we are willing to delay our request in ms.
48 1000 * 15, // 15 seconds.
49
50 // Time to keep an entry from being discarded even when it
51 // has no significant state, -1 to never discard.
52 -1,
53
54 // Don't use initial delay unless the last request was an error.
55 false,
56 };
57
30 } // namespace 58 } // namespace
31 59
32 ArcAuthContext::ArcAuthContext(Profile* profile) { 60 ArcAuthContext::ArcAuthContext(Profile* profile)
61 : retry_backoff_(&kRetryBackoffPolicy) {
33 // Reuse storage used in ARC OptIn platform app. 62 // Reuse storage used in ARC OptIn platform app.
34 const std::string site_url = base::StringPrintf( 63 const std::string site_url = base::StringPrintf(
35 "%s://%s/persist?%s", content::kGuestScheme, ArcSupportHost::kHostAppId, 64 "%s://%s/persist?%s", content::kGuestScheme, ArcSupportHost::kHostAppId,
36 ArcSupportHost::kStorageId); 65 ArcSupportHost::kStorageId);
37 storage_partition_ = content::BrowserContext::GetStoragePartitionForSite( 66 storage_partition_ = content::BrowserContext::GetStoragePartitionForSite(
38 profile, GURL(site_url)); 67 profile, GURL(site_url));
39 CHECK(storage_partition_); 68 CHECK(storage_partition_);
40 69
41 // Get token service and account ID to fetch auth tokens. 70 // Get token service and account ID to fetch auth tokens.
42 token_service_ = ProfileOAuth2TokenServiceFactory::GetForProfile(profile); 71 token_service_ = ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
(...skipping 12 matching lines...) Expand all
55 84
56 void ArcAuthContext::Prepare(const PrepareCallback& callback) { 85 void ArcAuthContext::Prepare(const PrepareCallback& callback) {
57 if (context_prepared_) { 86 if (context_prepared_) {
58 callback.Run(storage_partition_->GetURLRequestContext()); 87 callback.Run(storage_partition_->GetURLRequestContext());
59 return; 88 return;
60 } 89 }
61 90
62 callback_ = callback; 91 callback_ = callback;
63 token_service_->RemoveObserver(this); 92 token_service_->RemoveObserver(this);
64 refresh_token_timeout_.Stop(); 93 refresh_token_timeout_.Stop();
94 ResetFetchers();
95 retry_backoff_.Reset();
65 96
66 if (!token_service_->RefreshTokenIsAvailable(account_id_)) { 97 if (!token_service_->RefreshTokenIsAvailable(account_id_)) {
67 token_service_->AddObserver(this); 98 token_service_->AddObserver(this);
68 refresh_token_timeout_.Start(FROM_HERE, kRefreshTokenTimeout, this, 99 refresh_token_timeout_.Start(FROM_HERE, kRefreshTokenTimeout, this,
69 &ArcAuthContext::OnRefreshTokenTimeout); 100 &ArcAuthContext::OnRefreshTokenTimeout);
70 return; 101 return;
71 } 102 }
72 103
73 StartFetchers(); 104 StartFetchers();
74 } 105 }
(...skipping 18 matching lines...) Expand all
93 124
94 void ArcAuthContext::StartFetchers() { 125 void ArcAuthContext::StartFetchers() {
95 DCHECK(!refresh_token_timeout_.IsRunning()); 126 DCHECK(!refresh_token_timeout_.IsRunning());
96 ResetFetchers(); 127 ResetFetchers();
97 ubertoken_fetcher_.reset( 128 ubertoken_fetcher_.reset(
98 new UbertokenFetcher(token_service_, this, GaiaConstants::kChromeOSSource, 129 new UbertokenFetcher(token_service_, this, GaiaConstants::kChromeOSSource,
99 storage_partition_->GetURLRequestContext())); 130 storage_partition_->GetURLRequestContext()));
100 ubertoken_fetcher_->StartFetchingToken(account_id_); 131 ubertoken_fetcher_->StartFetchingToken(account_id_);
101 } 132 }
102 133
134 void ArcAuthContext::ResetFetchers() {
135 merger_fetcher_.reset();
136 ubertoken_fetcher_.reset();
137 retry_timeout_.Stop();
138 }
139
140 void ArcAuthContext::OnFetcherError(const GoogleServiceAuthError& error) {
141 ResetFetchers();
142 DCHECK(error.state() != GoogleServiceAuthError::NONE);
143 if (error.IsTransientError()) {
144 retry_backoff_.InformOfRequest(false);
145 if (retry_backoff_.failure_count() <= kMaxRetryAttempts) {
146 LOG(WARNING) << "Found transient error. Retry attempt "
147 << retry_backoff_.failure_count() << ".";
148 refresh_token_timeout_.Start(FROM_HERE,
149 retry_backoff_.GetTimeUntilRelease(), this,
150 &ArcAuthContext::StartFetchers);
151 return;
152 }
153 LOG(WARNING) << "Too many transient errors. Stop retrying.";
154 }
155 base::ResetAndReturn(&callback_).Run(nullptr);
156 }
157
103 void ArcAuthContext::OnUbertokenSuccess(const std::string& token) { 158 void ArcAuthContext::OnUbertokenSuccess(const std::string& token) {
104 ResetFetchers(); 159 ResetFetchers();
105 merger_fetcher_.reset( 160 merger_fetcher_.reset(
106 new GaiaAuthFetcher(this, GaiaConstants::kChromeOSSource, 161 new GaiaAuthFetcher(this, GaiaConstants::kChromeOSSource,
107 storage_partition_->GetURLRequestContext())); 162 storage_partition_->GetURLRequestContext()));
108 merger_fetcher_->StartMergeSession(token, std::string()); 163 merger_fetcher_->StartMergeSession(token, std::string());
109 } 164 }
110 165
111 void ArcAuthContext::OnUbertokenFailure(const GoogleServiceAuthError& error) { 166 void ArcAuthContext::OnUbertokenFailure(const GoogleServiceAuthError& error) {
112 LOG(WARNING) << "Failed to get ubertoken " << error.ToString() << "."; 167 LOG(WARNING) << "Failed to get ubertoken " << error.ToString() << ".";
113 ResetFetchers(); 168 OnFetcherError(error);
114 base::ResetAndReturn(&callback_).Run(nullptr);
115 } 169 }
116 170
117 void ArcAuthContext::OnMergeSessionSuccess(const std::string& data) { 171 void ArcAuthContext::OnMergeSessionSuccess(const std::string& data) {
172 VLOG_IF(1, retry_backoff_.failure_count())
173 << "Auth context was successfully prepared after retry.";
118 context_prepared_ = true; 174 context_prepared_ = true;
119 ResetFetchers(); 175 ResetFetchers();
120 base::ResetAndReturn(&callback_) 176 base::ResetAndReturn(&callback_)
121 .Run(storage_partition_->GetURLRequestContext()); 177 .Run(storage_partition_->GetURLRequestContext());
122 } 178 }
123 179
124 void ArcAuthContext::OnMergeSessionFailure( 180 void ArcAuthContext::OnMergeSessionFailure(
125 const GoogleServiceAuthError& error) { 181 const GoogleServiceAuthError& error) {
126 LOG(WARNING) << "Failed to merge gaia session " << error.ToString() << "."; 182 LOG(WARNING) << "Failed to merge gaia session " << error.ToString() << ".";
127 ResetFetchers(); 183 OnFetcherError(error);
128 base::ResetAndReturn(&callback_).Run(nullptr);
129 }
130
131 void ArcAuthContext::ResetFetchers() {
132 merger_fetcher_.reset();
133 ubertoken_fetcher_.reset();
134 } 184 }
135 185
136 } // namespace arc 186 } // namespace arc
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/arc/arc_auth_context.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698