| Index: chrome/browser/signin/oauth2_token_service.cc
|
| diff --git a/chrome/browser/signin/oauth2_token_service.cc b/chrome/browser/signin/oauth2_token_service.cc
|
| index e21911d00ffee39bea0bd97305fe4fb9eb5c1837..7dfcc38dec56560acb8f422ebed0905b7267f663 100644
|
| --- a/chrome/browser/signin/oauth2_token_service.cc
|
| +++ b/chrome/browser/signin/oauth2_token_service.cc
|
| @@ -20,21 +20,7 @@
|
| #include "google_apis/gaia/oauth2_access_token_fetcher.h"
|
| #include "net/url_request/url_request_context_getter.h"
|
|
|
| -namespace {
|
| -
|
| -// Maximum number of retries in fetching an OAuth2 access token.
|
| -const int kMaxFetchRetryNum = 5;
|
| -
|
| -// Returns an exponential backoff in milliseconds including randomness less than
|
| -// 1000 ms when retrying fetching an OAuth2 access token.
|
| -int64 ComputeExponentialBackOffMilliseconds(int retry_num) {
|
| - DCHECK(retry_num < kMaxFetchRetryNum);
|
| - int64 exponential_backoff_in_seconds = 1 << retry_num;
|
| - // Returns a backoff with randomness < 1000ms
|
| - return (exponential_backoff_in_seconds + base::RandDouble()) * 1000;
|
| -}
|
| -
|
| -} // namespace
|
| +int OAuth2TokenService::max_fetch_retry_num_ = 5;
|
|
|
| OAuth2TokenService::RequestImpl::RequestImpl(
|
| OAuth2TokenService::Consumer* consumer)
|
| @@ -119,7 +105,9 @@ class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer {
|
| base::WeakPtr<RequestImpl> waiting_request);
|
| void Start();
|
| void InformWaitingRequests();
|
| + void InformWaitingRequestsAndDelete();
|
| static bool ShouldRetry(const GoogleServiceAuthError& error);
|
| + int64 ComputeExponentialBackOffMilliseconds(int retry_num);
|
|
|
| // |oauth2_token_service_| remains valid for the life of this Fetcher, since
|
| // this Fetcher is destructed in the dtor of the OAuth2TokenService or is
|
| @@ -209,18 +197,14 @@ void OAuth2TokenService::Fetcher::OnGetTokenSuccess(
|
| scopes_,
|
| access_token_,
|
| expiration_date_);
|
| - // Deregisters itself from the service to prevent more waiting requests to
|
| - // be added when it calls back the waiting requests.
|
| - oauth2_token_service_->OnFetchComplete(this);
|
| - InformWaitingRequests();
|
| - base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
|
| + InformWaitingRequestsAndDelete();
|
| }
|
|
|
| void OAuth2TokenService::Fetcher::OnGetTokenFailure(
|
| const GoogleServiceAuthError& error) {
|
| fetcher_.reset();
|
|
|
| - if (ShouldRetry(error) && retry_number_ < kMaxFetchRetryNum) {
|
| + if (ShouldRetry(error) && retry_number_ < max_fetch_retry_num_) {
|
| int64 backoff = ComputeExponentialBackOffMilliseconds(retry_number_);
|
| ++retry_number_;
|
| retry_timer_.Stop();
|
| @@ -231,14 +215,18 @@ void OAuth2TokenService::Fetcher::OnGetTokenFailure(
|
| return;
|
| }
|
|
|
| - // Fetch completes.
|
| error_ = error;
|
| + InformWaitingRequestsAndDelete();
|
| +}
|
|
|
| - // Deregisters itself from the service to prevent more waiting requests to be
|
| - // added when it calls back the waiting requests.
|
| - oauth2_token_service_->OnFetchComplete(this);
|
| - InformWaitingRequests();
|
| - base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
|
| +// Returns an exponential backoff in milliseconds including randomness less than
|
| +// 1000 ms when retrying fetching an OAuth2 access token.
|
| +int64 OAuth2TokenService::Fetcher::ComputeExponentialBackOffMilliseconds(
|
| + int retry_num) {
|
| + DCHECK(retry_num < max_fetch_retry_num_);
|
| + int64 exponential_backoff_in_seconds = 1 << retry_num;
|
| + // Returns a backoff with randomness < 1000ms
|
| + return (exponential_backoff_in_seconds + base::RandDouble()) * 1000;
|
| }
|
|
|
| // static
|
| @@ -261,6 +249,14 @@ void OAuth2TokenService::Fetcher::InformWaitingRequests() {
|
| waiting_requests_.clear();
|
| }
|
|
|
| +void OAuth2TokenService::Fetcher::InformWaitingRequestsAndDelete() {
|
| + // Deregisters itself from the service to prevent more waiting requests to
|
| + // be added when it calls back the waiting requests.
|
| + oauth2_token_service_->OnFetchComplete(this);
|
| + InformWaitingRequests();
|
| + base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
|
| +}
|
| +
|
| void OAuth2TokenService::Fetcher::AddWaitingRequest(
|
| base::WeakPtr<OAuth2TokenService::RequestImpl> waiting_request) {
|
| waiting_requests_.push_back(waiting_request);
|
| @@ -325,9 +321,9 @@ scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest(
|
| if (HasCacheEntry(scopes))
|
| return StartCacheLookupRequest(scopes, consumer);
|
|
|
| - // Makes sure there is a pending fetcher for |scopes| and |refresh_token|.
|
| - // Adds |request| to the waiting request list of this fetcher so |request|
|
| - // will be called back when this fetcher finishes fetching.
|
| + // If there is already a pending fetcher for |scopes| and |refresh_token|,
|
| + // simply register this |request| for those results rather than starting
|
| + // a new fetcher.
|
| FetchParameters fetch_parameters = std::make_pair(refresh_token, scopes);
|
| std::map<FetchParameters, Fetcher*>::iterator iter =
|
| pending_fetchers_.find(fetch_parameters);
|
| @@ -335,6 +331,7 @@ scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest(
|
| iter->second->AddWaitingRequest(request->AsWeakPtr());
|
| return request.PassAs<Request>();
|
| }
|
| +
|
| pending_fetchers_[fetch_parameters] =
|
| Fetcher::CreateAndStart(this,
|
| request_context_getter_.get(),
|
| @@ -463,3 +460,9 @@ void OAuth2TokenService::ClearCache() {
|
| int OAuth2TokenService::cache_size_for_testing() const {
|
| return token_cache_.size();
|
| }
|
| +
|
| +void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing(
|
| + int max_retries) {
|
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
| + max_fetch_retry_num_ = max_retries;
|
| +}
|
|
|