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/core/background/pick_request_task.h" | 5 #include "components/offline_pages/core/background/pick_request_task.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 "base/time/time.h" | 9 #include "base/time/time.h" |
| 10 #include "components/offline_pages/core/background/device_conditions.h" | 10 #include "components/offline_pages/core/background/device_conditions.h" |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 } // namespace | 28 } // namespace |
| 29 | 29 |
| 30 namespace offline_pages { | 30 namespace offline_pages { |
| 31 | 31 |
| 32 PickRequestTask::PickRequestTask(RequestQueueStore* store, | 32 PickRequestTask::PickRequestTask(RequestQueueStore* store, |
| 33 OfflinerPolicy* policy, | 33 OfflinerPolicy* policy, |
| 34 RequestPickedCallback picked_callback, | 34 RequestPickedCallback picked_callback, |
| 35 RequestNotPickedCallback not_picked_callback, | 35 RequestNotPickedCallback not_picked_callback, |
| 36 RequestCountCallback request_count_callback, | 36 RequestCountCallback request_count_callback, |
| 37 DeviceConditions& device_conditions, | 37 DeviceConditions& device_conditions, |
| 38 const std::set<int64_t>& disabled_requests) | 38 const std::set<int64_t>& disabled_requests, |
| 39 std::vector<int64_t>& prioritized_requests) | |
| 39 : store_(store), | 40 : store_(store), |
| 40 policy_(policy), | 41 policy_(policy), |
| 41 picked_callback_(picked_callback), | 42 picked_callback_(picked_callback), |
| 42 not_picked_callback_(not_picked_callback), | 43 not_picked_callback_(not_picked_callback), |
| 43 request_count_callback_(request_count_callback), | 44 request_count_callback_(request_count_callback), |
| 44 disabled_requests_(disabled_requests), | 45 disabled_requests_(disabled_requests), |
| 46 prioritized_requests_(prioritized_requests), | |
| 45 weak_ptr_factory_(this) { | 47 weak_ptr_factory_(this) { |
| 46 device_conditions_.reset(new DeviceConditions(device_conditions)); | 48 device_conditions_.reset(new DeviceConditions(device_conditions)); |
| 47 } | 49 } |
| 48 | 50 |
| 49 PickRequestTask::~PickRequestTask() {} | 51 PickRequestTask::~PickRequestTask() {} |
| 50 | 52 |
| 51 void PickRequestTask::Run() { | 53 void PickRequestTask::Run() { |
| 52 GetRequests(); | 54 GetRequests(); |
| 53 } | 55 } |
| 54 | 56 |
| 55 void PickRequestTask::GetRequests() { | 57 void PickRequestTask::GetRequests() { |
| 56 // Get all the requests from the queue, we will classify them in the callback. | 58 // Get all the requests from the queue, we will classify them in the callback. |
| 57 store_->GetRequests( | 59 store_->GetRequests( |
| 58 base::Bind(&PickRequestTask::Choose, weak_ptr_factory_.GetWeakPtr())); | 60 base::Bind(&PickRequestTask::Choose, weak_ptr_factory_.GetWeakPtr())); |
| 59 } | 61 } |
| 60 | 62 |
| 61 void PickRequestTask::Choose( | 63 void PickRequestTask::Choose( |
| 62 bool success, | 64 bool success, |
| 63 std::vector<std::unique_ptr<SavePageRequest>> requests) { | 65 std::vector<std::unique_ptr<SavePageRequest>> requests) { |
| 64 // If there is nothing to do, return right away. | 66 // If there is nothing to do, return right away. |
| 65 if (requests.empty()) { | 67 if (requests.empty()) { |
| 66 request_count_callback_.Run(requests.size(), 0); | 68 request_count_callback_.Run(requests.size(), 0); |
| 67 not_picked_callback_.Run(!kNonUserRequestsFound, !kCleanupNeeded); | 69 not_picked_callback_.Run(!kNonUserRequestsFound, !kCleanupNeeded); |
| 68 TaskComplete(); | 70 TaskComplete(); |
| 69 return; | 71 return; |
| 70 } | 72 } |
| 71 | 73 |
| 72 // Pick the most deserving request for our conditions. | 74 // pick the most deserving request for our conditions. |
|
Pete Williamson
2017/03/07 19:06:04
This was better before. Accidental change?
romax
2017/03/07 20:41:45
Done.
| |
| 73 const SavePageRequest* picked_request = nullptr; | 75 const SavePageRequest* picked_request = nullptr; |
| 74 | 76 |
| 75 RequestCompareFunction comparator = nullptr; | 77 RequestCompareFunction comparator = nullptr; |
| 76 | 78 |
| 77 // Choose which comparison function to use based on policy. | 79 // Choose which comparison function to use based on policy. |
| 78 if (policy_->RetryCountIsMoreImportantThanRecency()) | 80 if (policy_->RetryCountIsMoreImportantThanRecency()) |
| 79 comparator = &PickRequestTask::RetryCountFirstCompareFunction; | 81 comparator = &PickRequestTask::RetryCountFirstCompareFunction; |
| 80 else | 82 else |
| 81 comparator = &PickRequestTask::RecencyFirstCompareFunction; | 83 comparator = &PickRequestTask::RecencyFirstCompareFunction; |
| 82 | 84 |
| 83 // TODO(petewil): Consider replacing this bool with a better named enum. | 85 // TODO(petewil): Consider replacing this bool with a better named enum. |
| 84 bool non_user_requested_tasks_remaining = false; | 86 bool non_user_requested_tasks_remaining = false; |
| 85 bool cleanup_needed = false; | 87 bool cleanup_needed = false; |
| 86 | 88 |
| 89 size_t request_size = requests.size(); | |
| 87 size_t available_request_count = 0; | 90 size_t available_request_count = 0; |
| 88 | 91 |
| 89 // Iterate once through the requests, keeping track of best candidate. | 92 std::vector<std::unique_ptr<SavePageRequest>> available_requests; |
| 93 | |
| 94 // Iterate through the requests, filter out unavailable requests and get other | |
| 95 // information (if cleanup is needed and number of non-user-requested | |
| 96 // requests). | |
| 90 for (unsigned i = 0; i < requests.size(); ++i) { | 97 for (unsigned i = 0; i < requests.size(); ++i) { |
| 91 // If the request is expired or has exceeded the retry count, skip it. | 98 // If the request is expired or has exceeded the retry count, skip it. |
| 92 if (OfflinerPolicyUtils::CheckRequestExpirationStatus(requests[i].get(), | 99 if (OfflinerPolicyUtils::CheckRequestExpirationStatus(requests[i].get(), |
| 93 policy_) != | 100 policy_) != |
| 94 OfflinerPolicyUtils::RequestExpirationStatus::VALID) { | 101 OfflinerPolicyUtils::RequestExpirationStatus::VALID) { |
| 95 cleanup_needed = true; | 102 cleanup_needed = true; |
| 96 continue; | 103 continue; |
| 97 } | 104 } |
| 98 | 105 // If the request is on the disabled list, skip it. |
| 99 // If the request is on the disabled list, skip it. | |
| 100 auto search = disabled_requests_.find(requests[i]->request_id()); | 106 auto search = disabled_requests_.find(requests[i]->request_id()); |
| 101 if (search != disabled_requests_.end()) | 107 if (search != disabled_requests_.end()) |
| 102 continue; | 108 continue; |
| 103 | 109 |
| 104 // If there are non-user-requested tasks remaining, we need to make sure | 110 // If there are non-user-requested tasks remaining, we need to make sure |
| 105 // that they are scheduled after we run out of user requested tasks. Here we | 111 // that they are scheduled after we run out of user requested tasks. Here we |
| 106 // detect if any exist. If we don't find any user-requested tasks, we will | 112 // detect if any exist. If we don't find any user-requested tasks, we will |
| 107 // inform the "not_picked_callback_" that it needs to schedule a task for | 113 // inform the "not_picked_callback_" that it needs to schedule a task for |
| 108 // non-user-requested items, which have different network and power needs. | 114 // non-user-requested items, which have different network and power needs. |
| 109 if (!requests[i]->user_requested()) | 115 if (!requests[i]->user_requested()) |
| 110 non_user_requested_tasks_remaining = true; | 116 non_user_requested_tasks_remaining = true; |
| 111 if (requests[i]->request_state() == | 117 if (requests[i]->request_state() == |
| 112 SavePageRequest::RequestState::AVAILABLE) { | 118 SavePageRequest::RequestState::AVAILABLE) { |
| 113 available_request_count++; | 119 available_request_count++; |
| 114 } | 120 } |
| 115 if (!RequestConditionsSatisfied(requests[i].get())) | 121 available_requests.push_back(std::move(requests[i])); |
| 116 continue; | 122 } |
| 117 if (IsNewRequestBetter(picked_request, requests[i].get(), comparator)) | 123 // Report the request queue counts. |
| 118 picked_request = requests[i].get(); | 124 request_count_callback_.Run(request_size, available_requests.size()); |
| 125 | |
| 126 // Search for and pick the prioritized requests which is not disabled and in | |
|
Pete Williamson
2017/03/07 19:06:04
Nit: requests -> request
romax
2017/03/07 20:41:45
Done.
| |
| 127 // the request queue. An assumption is that requests later in the vector have | |
| 128 // higher priority than earlier ones in the vector. | |
| 129 while (!picked_request && !prioritized_requests_.empty()) { | |
| 130 int64_t id = prioritized_requests_.back(); | |
| 131 for (unsigned i = 0; i < available_requests.size(); ++i) { | |
| 132 if (available_requests[i]->request_id() == id) { | |
| 133 picked_request = available_requests[i].get(); | |
| 134 break; | |
| 135 } | |
| 136 } | |
| 137 // Remove the prioritized requests which are not in request queue. | |
| 138 prioritized_requests_.pop_back(); | |
|
Pete Williamson
2017/03/07 19:06:04
Maybe instead of popping requests off the end of t
romax
2017/03/07 20:41:45
Done.
| |
| 119 } | 139 } |
| 120 | 140 |
| 121 // Report the request queue counts. | 141 if (!picked_request) { |
|
Pete Williamson
2017/03/07 19:06:04
add comment
// If no request was found from the pr
romax
2017/03/07 20:41:45
Done.
| |
| 122 request_count_callback_.Run(requests.size(), available_request_count); | 142 for (unsigned i = 0; i < available_requests.size(); ++i) { |
| 143 if (!RequestConditionsSatisfied(available_requests[i].get())) | |
| 144 continue; | |
| 145 if (IsNewRequestBetter(picked_request, available_requests[i].get(), | |
| 146 comparator)) { | |
| 147 picked_request = available_requests[i].get(); | |
| 148 } | |
| 149 } | |
| 150 } | |
| 123 | 151 |
| 124 // If we have a best request to try next, get the request coodinator to | 152 // If we have a best request to try next, get the request coodinator to |
| 125 // start it. Otherwise return that we have no candidates. | 153 // start it. Otherwise return that we have no candidates. |
| 126 if (picked_request != nullptr) { | 154 if (picked_request != nullptr) { |
| 127 picked_callback_.Run(*picked_request, cleanup_needed); | 155 picked_callback_.Run(*picked_request, cleanup_needed); |
| 128 } else { | 156 } else { |
| 129 not_picked_callback_.Run(non_user_requested_tasks_remaining, | 157 not_picked_callback_.Run(non_user_requested_tasks_remaining, |
| 130 cleanup_needed); | 158 cleanup_needed); |
| 131 } | 159 } |
| 132 | 160 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 int result = signum(difference.InMilliseconds()); | 274 int result = signum(difference.InMilliseconds()); |
| 247 | 275 |
| 248 // Flip the direction of comparison if policy prefers fewer retries. | 276 // Flip the direction of comparison if policy prefers fewer retries. |
| 249 if (policy_->ShouldPreferEarlierRequests()) | 277 if (policy_->ShouldPreferEarlierRequests()) |
| 250 result *= -1; | 278 result *= -1; |
| 251 | 279 |
| 252 return result; | 280 return result; |
| 253 } | 281 } |
| 254 | 282 |
| 255 } // namespace offline_pages | 283 } // namespace offline_pages |
| OLD | NEW |