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

Side by Side Diff: chrome/service/cloud_print/cloud_print_url_fetcher.cc

Issue 4194001: Implement exponential back-off mechanism and enforce it at the URLRequestHttpJob level. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/service/cloud_print/cloud_print_url_fetcher.h" 5 #include "chrome/service/cloud_print/cloud_print_url_fetcher.h"
6 6
7 #include "base/string_util.h" 7 #include "base/string_util.h"
8 #include "base/values.h" 8 #include "base/values.h"
9 #include "chrome/common/net/http_return.h" 9 #include "chrome/common/net/http_return.h"
10 #include "chrome/common/net/url_fetcher_protect.h"
11 #include "chrome/service/cloud_print/cloud_print_consts.h" 10 #include "chrome/service/cloud_print/cloud_print_consts.h"
12 #include "chrome/service/cloud_print/cloud_print_helpers.h" 11 #include "chrome/service/cloud_print/cloud_print_helpers.h"
13 #include "chrome/service/net/service_url_request_context.h" 12 #include "chrome/service/net/service_url_request_context.h"
14 #include "googleurl/src/gurl.h" 13 #include "googleurl/src/gurl.h"
14 #include "net/url_request/request_throttler_manager.h"
15 #include "net/url_request/url_request_status.h" 15 #include "net/url_request/url_request_status.h"
16 16
17 CloudPrintURLFetcher::CloudPrintURLFetcher() 17 CloudPrintURLFetcher::CloudPrintURLFetcher()
18 : delegate_(NULL), 18 : delegate_(NULL),
19 protect_entry_(NULL), 19 request_throttler_manager_(Singleton<RequestThrottlerManager>::get()),
20 num_retries_(0) { 20 num_retries_(0) {
21 } 21 }
22 22
23 void CloudPrintURLFetcher::StartGetRequest(const GURL& url, 23 void CloudPrintURLFetcher::StartGetRequest(const GURL& url,
24 Delegate* delegate, 24 Delegate* delegate,
25 const std::string& auth_token, 25 const std::string& auth_token,
26 const std::string& retry_policy) { 26 int max_retries) {
27 StartRequestHelper(url, URLFetcher::GET, delegate, auth_token, retry_policy, 27 StartRequestHelper(url, URLFetcher::GET, delegate, auth_token, max_retries,
28 std::string(), std::string()); 28 std::string(), std::string());
29 } 29 }
30 30
31 void CloudPrintURLFetcher::StartPostRequest( 31 void CloudPrintURLFetcher::StartPostRequest(
32 const GURL& url, 32 const GURL& url,
33 Delegate* delegate, 33 Delegate* delegate,
34 const std::string& auth_token, 34 const std::string& auth_token,
35 const std::string& retry_policy, 35 int max_retries,
36 const std::string& post_data_mime_type, 36 const std::string& post_data_mime_type,
37 const std::string& post_data) { 37 const std::string& post_data) {
38 StartRequestHelper(url, URLFetcher::POST, delegate, auth_token, retry_policy, 38 StartRequestHelper(url, URLFetcher::POST, delegate, auth_token, max_retries,
39 post_data_mime_type, post_data); 39 post_data_mime_type, post_data);
40 } 40 }
41 41
42 // URLFetcher::Delegate implementation. 42 // URLFetcher::Delegate implementation.
43 void CloudPrintURLFetcher::OnURLFetchComplete( 43 void CloudPrintURLFetcher::OnURLFetchComplete(
44 const URLFetcher* source, 44 const URLFetcher* source,
45 const GURL& url, 45 const GURL& url,
46 const URLRequestStatus& status, 46 const URLRequestStatus& status,
47 int response_code, 47 int response_code,
48 const ResponseCookies& cookies, 48 const ResponseCookies& cookies,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 action = delegate_->HandleJSONData(source, 81 action = delegate_->HandleJSONData(source,
82 url, 82 url,
83 response_dict, 83 response_dict,
84 succeeded); 84 succeeded);
85 else 85 else
86 action = RETRY_REQUEST; 86 action = RETRY_REQUEST;
87 } 87 }
88 } 88 }
89 // Retry the request if needed. 89 // Retry the request if needed.
90 if (action == RETRY_REQUEST) { 90 if (action == RETRY_REQUEST) {
91 int64 back_off_time = 91 scoped_refptr<RequestThrottlerEntryInterface> entry =
92 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::FAILURE); 92 request_throttler_manager_->RegisterRequestUrl(url);
93 // If the response code is greater than or equal to 500, then the back-off
94 // period has been increased at the network level; otherwise, explicitly
95 // call ReceivedContentWasMalformed() to count the current request as a
96 // failure and increase the back-off period.
97 if (response_code < 500)
98 entry->ReceivedContentWasMalformed();
99
93 ++num_retries_; 100 ++num_retries_;
94 int max_retries = protect_entry_->max_retries(); 101 if ((-1 != source->max_retries()) &&
95 if ((-1 != max_retries) && (num_retries_ > max_retries)) { 102 (num_retries_ > source->max_retries())) {
96 // Retry limit reached. Give up. 103 // Retry limit reached. Give up.
97 delegate_->OnRequestGiveUp(); 104 delegate_->OnRequestGiveUp();
98 } else { 105 } else {
99 // Either no retry limit specified or retry limit has not yet been 106 // Either no retry limit specified or retry limit has not yet been
100 // reached. Try again. 107 // reached. Try again.
101 MessageLoop::current()->PostDelayedTask( 108 MessageLoop::current()->PostDelayedTask(
102 FROM_HERE, 109 FROM_HERE,
103 NewRunnableMethod(this, &CloudPrintURLFetcher::StartRequestNow), 110 NewRunnableMethod(this, &CloudPrintURLFetcher::StartRequestNow),
104 back_off_time); 111 entry->GetRecommendedDelayForNextRequest());
Jói 2010/11/17 16:39:18 Same comment here on the sliding window - doesn't
yzshen 2010/11/19 23:51:36 I realize that we don't even need to wait here, si
105 } 112 }
106 } else {
107 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SUCCESS);
108 } 113 }
109 } 114 }
110 115
111 void CloudPrintURLFetcher::StartRequestHelper( 116 void CloudPrintURLFetcher::StartRequestHelper(
112 const GURL& url, 117 const GURL& url,
113 URLFetcher::RequestType request_type, 118 URLFetcher::RequestType request_type,
114 Delegate* delegate, 119 Delegate* delegate,
115 const std::string& auth_token, 120 const std::string& auth_token,
116 const std::string& retry_policy, 121 int max_retries,
117 const std::string& post_data_mime_type, 122 const std::string& post_data_mime_type,
118 const std::string& post_data) { 123 const std::string& post_data) {
119 DCHECK(delegate); 124 DCHECK(delegate);
120 request_.reset(new URLFetcher(url, request_type, this)); 125 request_.reset(new URLFetcher(url, request_type, this));
121 request_->set_request_context(GetRequestContextGetter()); 126 request_->set_request_context(GetRequestContextGetter());
122 // Since we implement our own retry logic, disable the retry in URLFetcher. 127 // Since we implement our own retry logic, disable the retry in URLFetcher.
123 request_->set_automatically_retry_on_5xx(false); 128 request_->set_automatically_retry_on_5xx(false);
129 request_->set_max_retries(max_retries);
124 delegate_ = delegate; 130 delegate_ = delegate;
125 std::string headers = "Authorization: GoogleLogin auth="; 131 std::string headers = "Authorization: GoogleLogin auth=";
126 headers += auth_token; 132 headers += auth_token;
127 headers += "\r\n"; 133 headers += "\r\n";
128 headers += kChromeCloudPrintProxyHeader; 134 headers += kChromeCloudPrintProxyHeader;
129 request_->set_extra_request_headers(headers); 135 request_->set_extra_request_headers(headers);
130 if (request_type == URLFetcher::POST) { 136 if (request_type == URLFetcher::POST) {
131 request_->set_upload_data(post_data_mime_type, post_data); 137 request_->set_upload_data(post_data_mime_type, post_data);
132 } 138 }
133 // Initialize the retry policy for this request. 139
134 protect_entry_ = 140 scoped_refptr<RequestThrottlerEntryInterface> entry =
135 URLFetcherProtectManager::GetInstance()->Register(retry_policy); 141 request_throttler_manager_->RegisterRequestUrl(url);
136 MessageLoop::current()->PostDelayedTask( 142 MessageLoop::current()->PostDelayedTask(
137 FROM_HERE, 143 FROM_HERE,
138 NewRunnableMethod(this, &CloudPrintURLFetcher::StartRequestNow), 144 NewRunnableMethod(this, &CloudPrintURLFetcher::StartRequestNow),
139 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SEND)); 145 entry->GetRecommendedDelayForNextRequest());
140 } 146 }
141 147
142 void CloudPrintURLFetcher::StartRequestNow() { 148 void CloudPrintURLFetcher::StartRequestNow() {
143 request_->Start(); 149 request_->Start();
144 } 150 }
145 151
146 URLRequestContextGetter* CloudPrintURLFetcher::GetRequestContextGetter() { 152 URLRequestContextGetter* CloudPrintURLFetcher::GetRequestContextGetter() {
147 ServiceURLRequestContextGetter* getter = 153 ServiceURLRequestContextGetter* getter =
148 new ServiceURLRequestContextGetter(); 154 new ServiceURLRequestContextGetter();
149 // Now set up the user agent for cloudprint. 155 // Now set up the user agent for cloudprint.
150 std::string user_agent = getter->user_agent(); 156 std::string user_agent = getter->user_agent();
151 base::StringAppendF(&user_agent, " %s", kCloudPrintUserAgent); 157 base::StringAppendF(&user_agent, " %s", kCloudPrintUserAgent);
152 getter->set_user_agent(user_agent); 158 getter->set_user_agent(user_agent);
153 return getter; 159 return getter;
154 } 160 }
155 161
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698