Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/suggestions/suggestions_service.h" | 5 #include "components/suggestions/suggestions_service.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 #include "net/base/net_errors.h" | 23 #include "net/base/net_errors.h" |
| 24 #include "net/base/url_util.h" | 24 #include "net/base/url_util.h" |
| 25 #include "net/http/http_response_headers.h" | 25 #include "net/http/http_response_headers.h" |
| 26 #include "net/http/http_status_code.h" | 26 #include "net/http/http_status_code.h" |
| 27 #include "net/http/http_util.h" | 27 #include "net/http/http_util.h" |
| 28 #include "net/url_request/url_fetcher.h" | 28 #include "net/url_request/url_fetcher.h" |
| 29 #include "net/url_request/url_request_status.h" | 29 #include "net/url_request/url_request_status.h" |
| 30 #include "url/gurl.h" | 30 #include "url/gurl.h" |
| 31 | 31 |
| 32 using base::CancelableClosure; | 32 using base::CancelableClosure; |
| 33 using base::TimeDelta; | |
| 34 using base::TimeTicks; | |
| 33 | 35 |
| 34 namespace suggestions { | 36 namespace suggestions { |
| 35 | 37 |
| 36 namespace { | 38 namespace { |
| 37 | 39 |
| 38 // Used to UMA log the state of the last response from the server. | 40 // Used to UMA log the state of the last response from the server. |
| 39 enum SuggestionsResponseState { | 41 enum SuggestionsResponseState { |
| 40 RESPONSE_EMPTY, | 42 RESPONSE_EMPTY, |
| 41 RESPONSE_INVALID, | 43 RESPONSE_INVALID, |
| 42 RESPONSE_VALID, | 44 RESPONSE_VALID, |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 67 const SuggestionsProfile& suggestions, | 69 const SuggestionsProfile& suggestions, |
| 68 std::vector<SuggestionsService::ResponseCallback>* requestors) { | 70 std::vector<SuggestionsService::ResponseCallback>* requestors) { |
| 69 std::vector<SuggestionsService::ResponseCallback> temp_requestors; | 71 std::vector<SuggestionsService::ResponseCallback> temp_requestors; |
| 70 temp_requestors.swap(*requestors); | 72 temp_requestors.swap(*requestors); |
| 71 std::vector<SuggestionsService::ResponseCallback>::iterator it; | 73 std::vector<SuggestionsService::ResponseCallback>::iterator it; |
| 72 for (it = temp_requestors.begin(); it != temp_requestors.end(); ++it) { | 74 for (it = temp_requestors.begin(); it != temp_requestors.end(); ++it) { |
| 73 if (!it->is_null()) it->Run(suggestions); | 75 if (!it->is_null()) it->Run(suggestions); |
| 74 } | 76 } |
| 75 } | 77 } |
| 76 | 78 |
| 77 // Default delay used when scheduling a blacklist request. | 79 // Default delay used when scheduling a request. |
| 78 const int kBlacklistDefaultDelaySec = 1; | 80 const TimeDelta kDefaultSchedulingDelay = TimeDelta::FromSeconds(1); |
|
Mathieu
2014/12/04 18:53:32
consider having a const int and rather initialize
manzagop (departed)
2014/12/05 15:13:22
Done. Went with local variables.
| |
| 79 | 81 |
| 80 // Multiplier on the delay used when scheduling a blacklist request, in case the | 82 // Multiplier on the delay used when re-scheduling a failed request. |
| 81 // last observed request was unsuccessful. | 83 const int kSchedulingBackoffMultiplier = 2; |
| 82 const int kBlacklistBackoffMultiplier = 2; | |
| 83 | 84 |
| 84 // Maximum valid delay for scheduling a request. Candidate delays larger than | 85 // Maximum valid delay for scheduling a request. Candidate delays larger than |
| 85 // this are rejected. This means the maximum backoff is at least 300 / 2, i.e. | 86 // this are rejected. This means the maximum backoff is at least 5 / 2 minutes. |
| 86 // 2.5 minutes. | 87 const TimeDelta kSchedulingMaxDelaySec = TimeDelta::FromMinutes(5); |
| 87 const int kBlacklistMaxDelaySec = 300; // 5 minutes | |
| 88 | 88 |
| 89 } // namespace | 89 } // namespace |
| 90 | 90 |
| 91 const char kSuggestionsFieldTrialName[] = "ChromeSuggestions"; | 91 const char kSuggestionsFieldTrialName[] = "ChromeSuggestions"; |
| 92 const char kSuggestionsFieldTrialControlParam[] = "control"; | 92 const char kSuggestionsFieldTrialControlParam[] = "control"; |
| 93 const char kSuggestionsFieldTrialStateEnabled[] = "enabled"; | 93 const char kSuggestionsFieldTrialStateEnabled[] = "enabled"; |
| 94 | 94 |
| 95 // TODO(mathp): Put this in TemplateURL. | 95 // TODO(mathp): Put this in TemplateURL. |
| 96 const char kSuggestionsURL[] = "https://www.google.com/chromesuggestions?t=2"; | 96 const char kSuggestionsURL[] = "https://www.google.com/chromesuggestions?t=2"; |
| 97 const char kSuggestionsBlacklistURLPrefix[] = | 97 const char kSuggestionsBlacklistURLPrefix[] = |
| 98 "https://www.google.com/chromesuggestions/blacklist?t=2&url="; | 98 "https://www.google.com/chromesuggestions/blacklist?t=2&url="; |
| 99 const char kSuggestionsBlacklistURLParam[] = "url"; | 99 const char kSuggestionsBlacklistURLParam[] = "url"; |
| 100 | 100 |
| 101 // The default expiry timeout is 72 hours. | 101 // The default expiry timeout is 72 hours. |
| 102 const int64 kDefaultExpiryUsec = 72 * base::Time::kMicrosecondsPerHour; | 102 const int64 kDefaultExpiryUsec = 72 * base::Time::kMicrosecondsPerHour; |
| 103 | 103 |
| 104 SuggestionsService::SuggestionsService( | 104 SuggestionsService::SuggestionsService( |
| 105 net::URLRequestContextGetter* url_request_context, | 105 net::URLRequestContextGetter* url_request_context, |
| 106 scoped_ptr<SuggestionsStore> suggestions_store, | 106 scoped_ptr<SuggestionsStore> suggestions_store, |
| 107 scoped_ptr<ImageManager> thumbnail_manager, | 107 scoped_ptr<ImageManager> thumbnail_manager, |
| 108 scoped_ptr<BlacklistStore> blacklist_store) | 108 scoped_ptr<BlacklistStore> blacklist_store) |
| 109 : url_request_context_(url_request_context), | 109 : url_request_context_(url_request_context), |
| 110 suggestions_store_(suggestions_store.Pass()), | 110 suggestions_store_(suggestions_store.Pass()), |
| 111 thumbnail_manager_(thumbnail_manager.Pass()), | 111 thumbnail_manager_(thumbnail_manager.Pass()), |
| 112 blacklist_store_(blacklist_store.Pass()), | 112 blacklist_store_(blacklist_store.Pass()), |
| 113 blacklist_delay_sec_(kBlacklistDefaultDelaySec), | 113 scheduling_delay_(kDefaultSchedulingDelay), |
| 114 suggestions_url_(kSuggestionsURL), | 114 suggestions_url_(kSuggestionsURL), |
| 115 blacklist_url_prefix_(kSuggestionsBlacklistURLPrefix), | 115 blacklist_url_prefix_(kSuggestionsBlacklistURLPrefix), |
| 116 weak_ptr_factory_(this) {} | 116 weak_ptr_factory_(this) {} |
| 117 | 117 |
| 118 SuggestionsService::~SuggestionsService() {} | 118 SuggestionsService::~SuggestionsService() {} |
| 119 | 119 |
| 120 // static | 120 // static |
| 121 bool SuggestionsService::IsControlGroup() { | 121 bool SuggestionsService::IsControlGroup() { |
| 122 return GetExperimentParam(kSuggestionsFieldTrialControlParam) == | 122 return GetExperimentParam(kSuggestionsFieldTrialControlParam) == |
| 123 kSuggestionsFieldTrialStateEnabled; | 123 kSuggestionsFieldTrialStateEnabled; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 147 } | 147 } |
| 148 | 148 |
| 149 void SuggestionsService::GetPageThumbnail( | 149 void SuggestionsService::GetPageThumbnail( |
| 150 const GURL& url, | 150 const GURL& url, |
| 151 base::Callback<void(const GURL&, const SkBitmap*)> callback) { | 151 base::Callback<void(const GURL&, const SkBitmap*)> callback) { |
| 152 thumbnail_manager_->GetImageForURL(url, callback); | 152 thumbnail_manager_->GetImageForURL(url, callback); |
| 153 } | 153 } |
| 154 | 154 |
| 155 void SuggestionsService::BlacklistURL( | 155 void SuggestionsService::BlacklistURL( |
| 156 const GURL& candidate_url, | 156 const GURL& candidate_url, |
| 157 const SuggestionsService::ResponseCallback& callback) { | 157 const SuggestionsService::ResponseCallback& callback, |
| 158 const base::Closure& fail_callback) { | |
| 158 DCHECK(thread_checker_.CalledOnValidThread()); | 159 DCHECK(thread_checker_.CalledOnValidThread()); |
| 160 | |
| 161 if (!blacklist_store_->BlacklistUrl(candidate_url)) { | |
| 162 fail_callback.Run(); | |
| 163 return; | |
| 164 } | |
| 165 | |
| 159 waiting_requestors_.push_back(callback); | 166 waiting_requestors_.push_back(callback); |
| 167 ServeFromCache(); | |
| 168 if (!pending_request_.get()) { | |
|
Mathieu
2014/12/04 18:53:33
put comment above here, mentioning why we only sch
manzagop (departed)
2014/12/05 15:13:22
Done.
| |
| 169 ScheduleBlacklistUpload(); | |
| 170 } | |
| 171 } | |
| 160 | 172 |
| 161 // Blacklist locally for immediate effect and serve the requestors. | 173 void SuggestionsService::UndoBlacklistURL( |
| 162 blacklist_store_->BlacklistUrl(candidate_url); | 174 const GURL& url, |
| 163 ServeFromCache(); | 175 const SuggestionsService::ResponseCallback& callback, |
| 164 | 176 const base::Closure& fail_callback) { |
| 165 // Send blacklisting request. Even if this request ends up not being sent | 177 DCHECK(thread_checker_.CalledOnValidThread()); |
| 166 // because of an ongoing request, a blacklist request is later scheduled. | 178 TimeDelta time_delta; |
| 167 // TODO(mathp): Currently, this will not send a request if there is already | 179 if (blacklist_store_->GetTimeUntilReadyForUpload(url, &time_delta) && |
| 168 // a request in flight (for suggestions or blacklist). Should we prioritize | 180 time_delta > TimeDelta::FromSeconds(0) && |
| 169 // blacklist requests since they actually carry a payload? | 181 blacklist_store_->RemoveUrl(url)) { |
| 170 IssueRequestIfNoneOngoing( | 182 // The URL was in the blacklist without being ready for upload and was |
|
Mathieu
2014/12/04 18:53:32
// The URL was not yet uploaded to the server and
manzagop (departed)
2014/12/05 15:13:22
Changed it, though not quite to what you propose b
| |
| 171 BuildBlacklistRequestURL(blacklist_url_prefix_, candidate_url)); | 183 // successfully removed. |
| 184 waiting_requestors_.push_back(callback); | |
| 185 ServeFromCache(); | |
| 186 return; | |
| 187 } | |
| 188 fail_callback.Run(); | |
| 172 } | 189 } |
| 173 | 190 |
| 174 // static | 191 // static |
| 175 bool SuggestionsService::GetBlacklistedUrl(const net::URLFetcher& request, | 192 bool SuggestionsService::GetBlacklistedUrl(const net::URLFetcher& request, |
| 176 GURL* url) { | 193 GURL* url) { |
| 177 bool is_blacklist_request = StartsWithASCII(request.GetOriginalURL().spec(), | 194 bool is_blacklist_request = StartsWithASCII(request.GetOriginalURL().spec(), |
| 178 kSuggestionsBlacklistURLPrefix, | 195 kSuggestionsBlacklistURLPrefix, |
| 179 true); | 196 true); |
| 180 if (!is_blacklist_request) return false; | 197 if (!is_blacklist_request) return false; |
| 181 | 198 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 212 } | 229 } |
| 213 } | 230 } |
| 214 | 231 |
| 215 void SuggestionsService::IssueRequestIfNoneOngoing(const GURL& url) { | 232 void SuggestionsService::IssueRequestIfNoneOngoing(const GURL& url) { |
| 216 // If there is an ongoing request, let it complete. | 233 // If there is an ongoing request, let it complete. |
| 217 if (pending_request_.get()) { | 234 if (pending_request_.get()) { |
| 218 return; | 235 return; |
| 219 } | 236 } |
| 220 pending_request_.reset(CreateSuggestionsRequest(url)); | 237 pending_request_.reset(CreateSuggestionsRequest(url)); |
| 221 pending_request_->Start(); | 238 pending_request_->Start(); |
| 222 last_request_started_time_ = base::TimeTicks::Now(); | 239 last_request_started_time_ = TimeTicks::Now(); |
| 223 } | 240 } |
| 224 | 241 |
| 225 net::URLFetcher* SuggestionsService::CreateSuggestionsRequest(const GURL& url) { | 242 net::URLFetcher* SuggestionsService::CreateSuggestionsRequest(const GURL& url) { |
| 226 net::URLFetcher* request = | 243 net::URLFetcher* request = |
| 227 net::URLFetcher::Create(0, url, net::URLFetcher::GET, this); | 244 net::URLFetcher::Create(0, url, net::URLFetcher::GET, this); |
| 228 request->SetLoadFlags(net::LOAD_DISABLE_CACHE); | 245 request->SetLoadFlags(net::LOAD_DISABLE_CACHE); |
| 229 request->SetRequestContext(url_request_context_); | 246 request->SetRequestContext(url_request_context_); |
| 230 // Add Chrome experiment state to the request headers. | 247 // Add Chrome experiment state to the request headers. |
| 231 net::HttpRequestHeaders headers; | 248 net::HttpRequestHeaders headers; |
| 232 variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders( | 249 variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders( |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 244 | 261 |
| 245 const net::URLRequestStatus& request_status = request->GetStatus(); | 262 const net::URLRequestStatus& request_status = request->GetStatus(); |
| 246 if (request_status.status() != net::URLRequestStatus::SUCCESS) { | 263 if (request_status.status() != net::URLRequestStatus::SUCCESS) { |
| 247 // This represents network errors (i.e. the server did not provide a | 264 // This represents network errors (i.e. the server did not provide a |
| 248 // response). | 265 // response). |
| 249 UMA_HISTOGRAM_SPARSE_SLOWLY("Suggestions.FailedRequestErrorCode", | 266 UMA_HISTOGRAM_SPARSE_SLOWLY("Suggestions.FailedRequestErrorCode", |
| 250 -request_status.error()); | 267 -request_status.error()); |
| 251 DVLOG(1) << "Suggestions server request failed with error: " | 268 DVLOG(1) << "Suggestions server request failed with error: " |
| 252 << request_status.error() << ": " | 269 << request_status.error() << ": " |
| 253 << net::ErrorToString(request_status.error()); | 270 << net::ErrorToString(request_status.error()); |
| 254 ScheduleBlacklistUpload(false); | 271 UpdateBlacklistDelay(false); |
| 272 ScheduleBlacklistUpload(); | |
| 255 return; | 273 return; |
| 256 } | 274 } |
| 257 | 275 |
| 258 const int response_code = request->GetResponseCode(); | 276 const int response_code = request->GetResponseCode(); |
| 259 UMA_HISTOGRAM_SPARSE_SLOWLY("Suggestions.FetchResponseCode", response_code); | 277 UMA_HISTOGRAM_SPARSE_SLOWLY("Suggestions.FetchResponseCode", response_code); |
| 260 if (response_code != net::HTTP_OK) { | 278 if (response_code != net::HTTP_OK) { |
| 261 // A non-200 response code means that server has no (longer) suggestions for | 279 // A non-200 response code means that server has no (longer) suggestions for |
| 262 // this user. Aggressively clear the cache. | 280 // this user. Aggressively clear the cache. |
| 263 suggestions_store_->ClearSuggestions(); | 281 suggestions_store_->ClearSuggestions(); |
| 264 ScheduleBlacklistUpload(false); | 282 UpdateBlacklistDelay(false); |
| 283 ScheduleBlacklistUpload(); | |
| 265 return; | 284 return; |
| 266 } | 285 } |
| 267 | 286 |
| 268 const base::TimeDelta latency = | 287 const TimeDelta latency = TimeTicks::Now() - last_request_started_time_; |
| 269 base::TimeTicks::Now() - last_request_started_time_; | |
| 270 UMA_HISTOGRAM_MEDIUM_TIMES("Suggestions.FetchSuccessLatency", latency); | 288 UMA_HISTOGRAM_MEDIUM_TIMES("Suggestions.FetchSuccessLatency", latency); |
| 271 | 289 |
| 272 // Handle a successful blacklisting. | 290 // Handle a successful blacklisting. |
| 273 GURL blacklisted_url; | 291 GURL blacklisted_url; |
| 274 if (GetBlacklistedUrl(*source, &blacklisted_url)) { | 292 if (GetBlacklistedUrl(*source, &blacklisted_url)) { |
| 275 blacklist_store_->RemoveUrl(blacklisted_url); | 293 blacklist_store_->RemoveUrl(blacklisted_url); |
| 276 } | 294 } |
| 277 | 295 |
| 278 std::string suggestions_data; | 296 std::string suggestions_data; |
| 279 bool success = request->GetResponseAsString(&suggestions_data); | 297 bool success = request->GetResponseAsString(&suggestions_data); |
| 280 DCHECK(success); | 298 DCHECK(success); |
| 281 | 299 |
| 282 // Parse the received suggestions and update the cache, or take proper action | 300 // Parse the received suggestions and update the cache, or take proper action |
| 283 // in the case of invalid response. | 301 // in the case of invalid response. |
| 284 SuggestionsProfile suggestions; | 302 SuggestionsProfile suggestions; |
| 285 if (suggestions_data.empty()) { | 303 if (suggestions_data.empty()) { |
| 286 LogResponseState(RESPONSE_EMPTY); | 304 LogResponseState(RESPONSE_EMPTY); |
| 287 suggestions_store_->ClearSuggestions(); | 305 suggestions_store_->ClearSuggestions(); |
| 288 } else if (suggestions.ParseFromString(suggestions_data)) { | 306 } else if (suggestions.ParseFromString(suggestions_data)) { |
| 289 LogResponseState(RESPONSE_VALID); | 307 LogResponseState(RESPONSE_VALID); |
| 290 int64 now_usec = (base::Time::NowFromSystemTime() - base::Time::UnixEpoch()) | 308 int64 now_usec = (base::Time::NowFromSystemTime() - base::Time::UnixEpoch()) |
| 291 .ToInternalValue(); | 309 .ToInternalValue(); |
| 292 SetDefaultExpiryTimestamp(&suggestions, now_usec + kDefaultExpiryUsec); | 310 SetDefaultExpiryTimestamp(&suggestions, now_usec + kDefaultExpiryUsec); |
| 293 suggestions_store_->StoreSuggestions(suggestions); | 311 suggestions_store_->StoreSuggestions(suggestions); |
| 294 } else { | 312 } else { |
| 295 LogResponseState(RESPONSE_INVALID); | 313 LogResponseState(RESPONSE_INVALID); |
| 296 } | 314 } |
| 297 | 315 |
| 298 ScheduleBlacklistUpload(true); | 316 UpdateBlacklistDelay(true); |
| 317 ScheduleBlacklistUpload(); | |
| 299 } | 318 } |
| 300 | 319 |
| 301 void SuggestionsService::Shutdown() { | 320 void SuggestionsService::Shutdown() { |
| 302 // Cancel pending request, then serve existing requestors from cache. | 321 // Cancel pending request, then serve existing requestors from cache. |
| 303 pending_request_.reset(NULL); | 322 pending_request_.reset(NULL); |
| 304 ServeFromCache(); | 323 ServeFromCache(); |
| 305 } | 324 } |
| 306 | 325 |
| 307 void SuggestionsService::ServeFromCache() { | 326 void SuggestionsService::ServeFromCache() { |
| 308 SuggestionsProfile suggestions; | 327 SuggestionsProfile suggestions; |
| 309 // In case of empty cache or error, |suggestions| stays empty. | 328 // In case of empty cache or error, |suggestions| stays empty. |
| 310 suggestions_store_->LoadSuggestions(&suggestions); | 329 suggestions_store_->LoadSuggestions(&suggestions); |
| 311 thumbnail_manager_->Initialize(suggestions); | 330 thumbnail_manager_->Initialize(suggestions); |
| 312 FilterAndServe(&suggestions); | 331 FilterAndServe(&suggestions); |
| 313 } | 332 } |
| 314 | 333 |
| 315 void SuggestionsService::FilterAndServe(SuggestionsProfile* suggestions) { | 334 void SuggestionsService::FilterAndServe(SuggestionsProfile* suggestions) { |
| 316 blacklist_store_->FilterSuggestions(suggestions); | 335 blacklist_store_->FilterSuggestions(suggestions); |
| 317 DispatchRequestsAndClear(*suggestions, &waiting_requestors_); | 336 DispatchRequestsAndClear(*suggestions, &waiting_requestors_); |
| 318 } | 337 } |
| 319 | 338 |
| 320 void SuggestionsService::ScheduleBlacklistUpload(bool last_request_successful) { | 339 void SuggestionsService::ScheduleBlacklistUpload() { |
| 321 DCHECK(thread_checker_.CalledOnValidThread()); | 340 DCHECK(thread_checker_.CalledOnValidThread()); |
| 322 | 341 TimeDelta time_delta; |
| 323 UpdateBlacklistDelay(last_request_successful); | 342 if (blacklist_store_->GetTimeUntilReadyForUpload(&time_delta)) { |
| 324 | 343 // Blacklist cache is not empty: schedule. |
| 325 // Schedule a blacklist upload task. | |
| 326 GURL blacklist_url; | |
| 327 if (blacklist_store_->GetFirstUrlFromBlacklist(&blacklist_url)) { | |
| 328 base::Closure blacklist_cb = | 344 base::Closure blacklist_cb = |
| 329 base::Bind(&SuggestionsService::UploadOneFromBlacklist, | 345 base::Bind(&SuggestionsService::UploadOneFromBlacklist, |
| 330 weak_ptr_factory_.GetWeakPtr()); | 346 weak_ptr_factory_.GetWeakPtr()); |
| 331 base::MessageLoopProxy::current()->PostDelayedTask( | 347 base::MessageLoopProxy::current()->PostDelayedTask( |
| 332 FROM_HERE, blacklist_cb, | 348 FROM_HERE, blacklist_cb, time_delta + scheduling_delay_); |
| 333 base::TimeDelta::FromSeconds(blacklist_delay_sec_)); | |
| 334 } | 349 } |
| 335 } | 350 } |
| 336 | 351 |
| 337 void SuggestionsService::UploadOneFromBlacklist() { | 352 void SuggestionsService::UploadOneFromBlacklist() { |
| 338 DCHECK(thread_checker_.CalledOnValidThread()); | 353 DCHECK(thread_checker_.CalledOnValidThread()); |
| 339 | 354 |
| 340 GURL blacklist_url; | 355 GURL blacklist_url; |
| 341 if (!blacklist_store_->GetFirstUrlFromBlacklist(&blacklist_url)) | 356 if (blacklist_store_->GetCandidateForUpload(&blacklist_url)) { |
| 342 return; // Local blacklist is empty. | 357 // Issue a blacklisting request. Even if this request ends up not being sent |
| 358 // because of an ongoing request, a blacklist request is later scheduled. | |
| 359 IssueRequestIfNoneOngoing( | |
| 360 BuildBlacklistRequestURL(blacklist_url_prefix_, blacklist_url)); | |
| 361 return; | |
| 362 } | |
| 343 | 363 |
| 344 // Send blacklisting request. Even if this request ends up not being sent | 364 // Even though there's no candidate for upload, the blacklist might not be |
| 345 // because of an ongoing request, a blacklist request is later scheduled. | 365 // empty. |
| 346 IssueRequestIfNoneOngoing( | 366 ScheduleBlacklistUpload(); |
| 347 BuildBlacklistRequestURL(blacklist_url_prefix_, blacklist_url)); | |
| 348 } | 367 } |
| 349 | 368 |
| 350 void SuggestionsService::UpdateBlacklistDelay(bool last_request_successful) { | 369 void SuggestionsService::UpdateBlacklistDelay(bool last_request_successful) { |
| 351 DCHECK(thread_checker_.CalledOnValidThread()); | 370 DCHECK(thread_checker_.CalledOnValidThread()); |
| 352 | 371 |
| 353 if (last_request_successful) { | 372 if (last_request_successful) { |
| 354 blacklist_delay_sec_ = kBlacklistDefaultDelaySec; | 373 scheduling_delay_ = kDefaultSchedulingDelay; |
| 355 } else { | 374 } else { |
| 356 int candidate_delay = blacklist_delay_sec_ * kBlacklistBackoffMultiplier; | 375 TimeDelta candidate_delay = |
| 357 if (candidate_delay < kBlacklistMaxDelaySec) | 376 scheduling_delay_ * kSchedulingBackoffMultiplier; |
| 358 blacklist_delay_sec_ = candidate_delay; | 377 if (candidate_delay < kSchedulingMaxDelaySec) |
| 378 scheduling_delay_ = candidate_delay; | |
| 359 } | 379 } |
| 360 } | 380 } |
| 361 | 381 |
| 362 } // namespace suggestions | 382 } // namespace suggestions |
| OLD | NEW |