Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "components/offline_pages/background/request_picker.h" | 5 #include "components/offline_pages/background/request_picker.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "components/offline_pages/background/save_page_request.h" | 9 #include "components/offline_pages/background/save_page_request.h" |
| 10 | 10 |
| 11 namespace { | 11 namespace { |
| 12 template <typename T> | 12 template <typename T> |
| 13 int signum(T t) { | 13 int signum(T t) { |
| 14 return (T(0) < t) - (t < T(0)); | 14 return (T(0) < t) - (t < T(0)); |
| 15 } | 15 } |
| 16 | 16 |
| 17 #define CALL_MEMBER_FUNCTION(object,ptrToMember) ((object)->*(ptrToMember)) | 17 #define CALL_MEMBER_FUNCTION(object,ptrToMember) ((object)->*(ptrToMember)) |
| 18 } // namespace | 18 } // namespace |
| 19 | 19 |
| 20 namespace offline_pages { | 20 namespace offline_pages { |
| 21 | 21 |
| 22 RequestPicker::RequestPicker( | 22 RequestPicker::RequestPicker(RequestQueue* requestQueue, |
| 23 RequestQueue* requestQueue, OfflinerPolicy* policy) | 23 OfflinerPolicy* policy, |
| 24 RequestCoordinator* coordinator) | |
| 24 : queue_(requestQueue), | 25 : queue_(requestQueue), |
| 25 policy_(policy), | 26 policy_(policy), |
| 27 coordinator_(coordinator), | |
| 26 fewer_retries_better_(false), | 28 fewer_retries_better_(false), |
| 27 earlier_requests_better_(false), | 29 earlier_requests_better_(false), |
| 28 weak_ptr_factory_(this) {} | 30 weak_ptr_factory_(this) {} |
| 29 | 31 |
| 30 RequestPicker::~RequestPicker() {} | 32 RequestPicker::~RequestPicker() {} |
| 31 | 33 |
| 32 // Entry point for the async operation to choose the next request. | 34 // Entry point for the async operation to choose the next request. |
| 33 void RequestPicker::ChooseNextRequest( | 35 void RequestPicker::ChooseNextRequest( |
| 34 RequestCoordinator::RequestPickedCallback picked_callback, | 36 RequestCoordinator::RequestPickedCallback picked_callback, |
| 35 RequestCoordinator::RequestQueueEmptyCallback empty_callback, | 37 RequestCoordinator::RequestQueueEmptyCallback empty_callback, |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 48 // request to operate on (if any). | 50 // request to operate on (if any). |
| 49 void RequestPicker::GetRequestResultCallback( | 51 void RequestPicker::GetRequestResultCallback( |
| 50 RequestQueue::GetRequestsResult, | 52 RequestQueue::GetRequestsResult, |
| 51 const std::vector<SavePageRequest>& requests) { | 53 const std::vector<SavePageRequest>& requests) { |
| 52 // If there is nothing to do, return right away. | 54 // If there is nothing to do, return right away. |
| 53 if (requests.size() == 0) { | 55 if (requests.size() == 0) { |
| 54 empty_callback_.Run(); | 56 empty_callback_.Run(); |
| 55 return; | 57 return; |
| 56 } | 58 } |
| 57 | 59 |
| 60 // Get the expired requests to be removed from the queue, and the valid ones | |
| 61 // from which to pick the next request. | |
| 62 std::vector<SavePageRequest> valid_requests; | |
| 63 std::vector<SavePageRequest> expired_requests; | |
| 64 SplitRequests(requests, valid_requests, expired_requests); | |
| 65 std::vector<int64_t> expired_request_ids; | |
| 66 for (auto request : expired_requests) | |
| 67 expired_request_ids.push_back(request.request_id()); | |
| 68 | |
| 69 queue_->RemoveRequests(expired_request_ids, | |
| 70 base::Bind(&RequestPicker::OnRequestExpired, | |
| 71 weak_ptr_factory_.GetWeakPtr())); | |
| 72 | |
| 58 // Pick the most deserving request for our conditions. | 73 // Pick the most deserving request for our conditions. |
| 59 const SavePageRequest* picked_request = nullptr; | 74 const SavePageRequest* picked_request = nullptr; |
| 60 | 75 |
| 61 RequestCompareFunction comparator = nullptr; | 76 RequestCompareFunction comparator = nullptr; |
| 62 | 77 |
| 63 // Choose which comparison function to use based on policy. | 78 // Choose which comparison function to use based on policy. |
| 64 if (policy_->RetryCountIsMoreImportantThanRecency()) | 79 if (policy_->RetryCountIsMoreImportantThanRecency()) |
| 65 comparator = &RequestPicker::RetryCountFirstCompareFunction; | 80 comparator = &RequestPicker::RetryCountFirstCompareFunction; |
| 66 else | 81 else |
| 67 comparator = &RequestPicker::RecencyFirstCompareFunction; | 82 comparator = &RequestPicker::RecencyFirstCompareFunction; |
| 68 | 83 |
| 69 // Iterate once through the requests, keeping track of best candidate. | 84 // Iterate once through the requests, keeping track of best candidate. |
| 70 for (unsigned i = 0; i < requests.size(); ++i) { | 85 for (unsigned i = 0; i < valid_requests.size(); ++i) { |
| 71 if (!RequestConditionsSatisfied(requests[i])) | 86 if (!RequestConditionsSatisfied(valid_requests[i])) |
| 72 continue; | 87 continue; |
| 73 if (IsNewRequestBetter(picked_request, &(requests[i]), comparator)) | 88 if (IsNewRequestBetter(picked_request, &(valid_requests[i]), comparator)) |
| 74 picked_request = &(requests[i]); | 89 picked_request = &(valid_requests[i]); |
| 75 } | 90 } |
| 76 | 91 |
| 77 // If we have a best request to try next, get the request coodinator to | 92 // If we have a best request to try next, get the request coodinator to |
| 78 // start it. Otherwise return that we have no candidates. | 93 // start it. Otherwise return that we have no candidates. |
| 79 if (picked_request != nullptr) { | 94 if (picked_request != nullptr) { |
| 80 picked_callback_.Run(*picked_request); | 95 picked_callback_.Run(*picked_request); |
| 81 } else { | 96 } else { |
| 82 empty_callback_.Run(); | 97 empty_callback_.Run(); |
| 83 } | 98 } |
| 84 } | 99 } |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 216 base::TimeDelta difference = left->creation_time() - right->creation_time(); | 231 base::TimeDelta difference = left->creation_time() - right->creation_time(); |
| 217 int result = signum(difference.InMilliseconds()); | 232 int result = signum(difference.InMilliseconds()); |
| 218 | 233 |
| 219 // Flip the direction of comparison if policy prefers fewer retries. | 234 // Flip the direction of comparison if policy prefers fewer retries. |
| 220 if (earlier_requests_better_) | 235 if (earlier_requests_better_) |
| 221 result *= -1; | 236 result *= -1; |
| 222 | 237 |
| 223 return result; | 238 return result; |
| 224 } | 239 } |
| 225 | 240 |
| 241 // Split all requests into expired ones and still valid ones. | |
| 242 void RequestPicker::SplitRequests( | |
| 243 const std::vector<SavePageRequest>& requests, | |
| 244 std::vector<SavePageRequest>& valid_requests, | |
| 245 std::vector<SavePageRequest>& expired_requests) { | |
| 246 for (SavePageRequest request : requests) { | |
| 247 if (base::Time::Now() - request.creation_time() >= | |
| 248 base::TimeDelta::FromSeconds(kRequestExpirationTimeInSeconds)) { | |
| 249 expired_requests.push_back(request); | |
| 250 } else { | |
| 251 valid_requests.push_back(request); | |
| 252 } | |
| 253 } | |
| 254 } | |
| 255 | |
| 256 // Callback used after expired requests are deleted from the queue and notifies | |
| 257 // the coordinator. | |
| 258 void RequestPicker::OnRequestExpired( | |
| 259 const RequestQueue::UpdateMultipleRequestResults& results, | |
| 260 const std::vector<SavePageRequest>& requests) { | |
| 261 for (auto request : requests) | |
| 262 coordinator_->NotifyFailed(request, | |
|
Pete Williamson
2016/08/16 23:40:46
This will change to coordinator_->NotifiyCompleted
romax
2016/08/17 20:07:59
Done.
| |
| 263 RequestCoordinator::SavePageStatus::EXPIRED); | |
| 264 } | |
| 265 | |
| 226 } // namespace offline_pages | 266 } // namespace offline_pages |
| OLD | NEW |