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

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

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