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

Unified Diff: components/offline_pages/background/pick_request_task.cc

Issue 2473553004: Request Picker task (Closed)
Patch Set: merge with latest Created 4 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 side-by-side diff with in-line comments
Download patch
Index: components/offline_pages/background/pick_request_task.cc
diff --git a/components/offline_pages/background/request_picker.cc b/components/offline_pages/background/pick_request_task.cc
similarity index 57%
rename from components/offline_pages/background/request_picker.cc
rename to components/offline_pages/background/pick_request_task.cc
index c1d27838165d837bb70bc28bf3768e63a597441d..3de14dd4d5cee57ed88d727ab8e41604cabc5829 100644
--- a/components/offline_pages/background/request_picker.cc
+++ b/components/offline_pages/background/pick_request_task.cc
@@ -2,10 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/offline_pages/background/request_picker.h"
+#include "components/offline_pages/background/pick_request_task.h"
#include "base/bind.h"
#include "base/logging.h"
+#include "base/time/time.h"
+#include "components/offline_pages/background/device_conditions.h"
+#include "components/offline_pages/background/offliner_policy.h"
+#include "components/offline_pages/background/request_coordinator_event_logger.h"
+#include "components/offline_pages/background/request_notifier.h"
+#include "components/offline_pages/background/request_queue_store.h"
#include "components/offline_pages/background/save_page_request.h"
namespace {
@@ -19,62 +25,63 @@ int signum(T t) {
namespace offline_pages {
-RequestPicker::RequestPicker(RequestQueue* requestQueue,
- OfflinerPolicy* policy,
- RequestNotifier* notifier,
- RequestCoordinatorEventLogger* event_logger)
- : queue_(requestQueue),
+PickRequestTask::PickRequestTask(RequestQueueStore* store,
+ OfflinerPolicy* policy,
+ RequestNotifier* notifier,
+ RequestCoordinatorEventLogger* event_logger,
+ RequestPickedCallback picked_callback,
+ RequestNotPickedCallback not_picked_callback,
+ DeviceConditions& device_conditions,
+ const std::set<int64_t>& disabled_requests)
+ : store_(store),
policy_(policy),
notifier_(notifier),
event_logger_(event_logger),
- fewer_retries_better_(false),
- earlier_requests_better_(false),
- weak_ptr_factory_(this) {}
-
-RequestPicker::~RequestPicker() {}
-
-// Entry point for the async operation to choose the next request.
-void RequestPicker::ChooseNextRequest(
- RequestCoordinator::RequestPickedCallback picked_callback,
- RequestCoordinator::RequestNotPickedCallback not_picked_callback,
- DeviceConditions* device_conditions,
- const std::set<int64_t>& disabled_requests) {
- picked_callback_ = picked_callback;
- not_picked_callback_ = not_picked_callback;
- fewer_retries_better_ = policy_->ShouldPreferUntriedRequests();
- earlier_requests_better_ = policy_->ShouldPreferEarlierRequests();
- current_conditions_.reset(new DeviceConditions(*device_conditions));
- // Get all requests from queue (there is no filtering mechanism).
- queue_->GetRequests(base::Bind(&RequestPicker::GetRequestResultCallback,
- weak_ptr_factory_.GetWeakPtr(),
- disabled_requests));
+ picked_callback_(picked_callback),
+ not_picked_callback_(not_picked_callback),
+ disabled_requests_(disabled_requests),
+ weak_ptr_factory_(this) {
+ device_conditions_.reset(new DeviceConditions(device_conditions));
}
-// When we get contents from the queue, use them to pick the next
-// request to operate on (if any).
-void RequestPicker::GetRequestResultCallback(
- const std::set<int64_t>& disabled_requests,
- RequestQueue::GetRequestsResult,
+PickRequestTask::~PickRequestTask() {}
+
+void PickRequestTask::Run() {
+ // Get all the requests from the queue, we will classify them in the callback.
+ store_->GetRequests(base::Bind(&PickRequestTask::ChooseAndPrune,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void PickRequestTask::ChooseAndPrune(
+ bool success,
std::vector<std::unique_ptr<SavePageRequest>> requests) {
// If there is nothing to do, return right away.
if (requests.size() == 0) {
not_picked_callback_.Run(false);
+ TaskComplete();
return;
}
// Get the expired requests to be removed from the queue, and the valid ones
// from which to pick the next request.
std::vector<std::unique_ptr<SavePageRequest>> valid_requests;
- std::vector<std::unique_ptr<SavePageRequest>> expired_requests;
- SplitRequests(std::move(requests), &valid_requests, &expired_requests);
std::vector<int64_t> expired_request_ids;
- for (const auto& request : expired_requests)
- expired_request_ids.push_back(request->request_id());
+ SplitRequests(std::move(requests), &valid_requests, &expired_request_ids);
- queue_->RemoveRequests(expired_request_ids,
- base::Bind(&RequestPicker::OnRequestExpired,
- weak_ptr_factory_.GetWeakPtr()));
+ // Continue processing by choosing a request.
+ ChooseRequestAndCallback(std::move(valid_requests));
+ // Continue processing by handling expired requests, if any.
+ if (expired_request_ids.size() == 0) {
+ TaskComplete();
+ return;
+ }
+
+ RemoveStaleRequests(std::move(expired_request_ids));
+}
+
+void PickRequestTask::ChooseRequestAndCallback(
+ std::vector<std::unique_ptr<SavePageRequest>> valid_requests) {
// Pick the most deserving request for our conditions.
const SavePageRequest* picked_request = nullptr;
@@ -82,18 +89,24 @@ void RequestPicker::GetRequestResultCallback(
// Choose which comparison function to use based on policy.
if (policy_->RetryCountIsMoreImportantThanRecency())
- comparator = &RequestPicker::RetryCountFirstCompareFunction;
+ comparator = &PickRequestTask::RetryCountFirstCompareFunction;
else
- comparator = &RequestPicker::RecencyFirstCompareFunction;
+ comparator = &PickRequestTask::RecencyFirstCompareFunction;
- // Iterate once through the requests, keeping track of best candidate.
+ // TODO(petewil): Consider replacing this bool with a better named enum.
bool non_user_requested_tasks_remaining = false;
+
+ // Iterate once through the requests, keeping track of best candidate.
for (unsigned i = 0; i < valid_requests.size(); ++i) {
// If the request is on the disabled list, skip it.
- auto search = disabled_requests.find(valid_requests[i]->request_id());
- if (search != disabled_requests.end()) {
+ auto search = disabled_requests_.find(valid_requests[i]->request_id());
+ if (search != disabled_requests_.end())
continue;
- }
+ // If there are non-user-requested tasks remaining, we need to make sure
+ // that they are scheduled after we run out of user requested tasks. Here we
+ // detect if any exist. If we don't find any user-requested tasks, we will
+ // inform the "not_picked_callback_" that it needs to schedule a task for
+ // non-user-requested items, which have different network and power needs.
if (!valid_requests[i]->user_requested())
non_user_requested_tasks_remaining = true;
if (!RequestConditionsSatisfied(valid_requests[i].get()))
@@ -104,33 +117,73 @@ void RequestPicker::GetRequestResultCallback(
// If we have a best request to try next, get the request coodinator to
// start it. Otherwise return that we have no candidates.
- if (picked_request != nullptr) {
+ if (picked_request != nullptr)
picked_callback_.Run(*picked_request);
- } else {
+ else
not_picked_callback_.Run(non_user_requested_tasks_remaining);
+}
+
+// Continue the async part of the processing by deleting the expired requests.
+// TODO(petewil): Does that really need to be done on the task queue? Hard to
+// see how we need to wait for it before starting the next task. OTOH, we'd hate
+// to do a second slow DB operation to get entries a second time, and waiting
+// until this is done will make sure other gets don't see these old entries.
+// Consider moving this to a fresh task type to clean the queue.
+void PickRequestTask::RemoveStaleRequests(
+ std::vector<int64_t> stale_request_ids) {
+ store_->RemoveRequests(stale_request_ids,
+ base::Bind(&PickRequestTask::OnRequestsExpired,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void PickRequestTask::OnRequestsExpired(
+ std::unique_ptr<UpdateRequestsResult> result) {
+ RequestNotifier::BackgroundSavePageResult save_page_result(
+ RequestNotifier::BackgroundSavePageResult::EXPIRED);
+ for (const auto& request : result->updated_items) {
+ event_logger_->RecordDroppedSavePageRequest(
+ request.client_id().name_space, save_page_result, request.request_id());
+ notifier_->NotifyCompleted(request, save_page_result);
+ }
+
+ // The task is now done, return control to the task queue.
+ TaskComplete();
+}
+
+void PickRequestTask::SplitRequests(
+ std::vector<std::unique_ptr<SavePageRequest>> requests,
+ std::vector<std::unique_ptr<SavePageRequest>>* valid_requests,
+ std::vector<int64_t>* expired_request_ids) {
+ for (auto& request : requests) {
+ if (base::Time::Now() - request->creation_time() >=
+ base::TimeDelta::FromSeconds(kRequestExpirationTimeInSeconds)) {
+ expired_request_ids->push_back(request->request_id());
+ } else {
+ valid_requests->push_back(std::move(request));
+ }
}
}
// Filter out requests that don't meet the current conditions. For instance, if
// this is a predictive request, and we are not on WiFi, it should be ignored
// this round.
-bool RequestPicker::RequestConditionsSatisfied(const SavePageRequest* request) {
+bool PickRequestTask::RequestConditionsSatisfied(
+ const SavePageRequest* request) {
// If the user did not request the page directly, make sure we are connected
// to power and have WiFi and sufficient battery remaining before we take this
// request.
-
- if (!current_conditions_->IsPowerConnected() &&
+ if (!device_conditions_->IsPowerConnected() &&
policy_->PowerRequired(request->user_requested())) {
return false;
}
- if (current_conditions_->GetNetConnectionType() !=
+ if (device_conditions_->GetNetConnectionType() !=
net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI &&
policy_->UnmeteredNetworkRequired(request->user_requested())) {
return false;
}
- if (current_conditions_->GetBatteryPercentage() <
+ if (device_conditions_->GetBatteryPercentage() <
policy_->BatteryPercentageRequired(request->user_requested())) {
return false;
}
@@ -151,9 +204,8 @@ bool RequestPicker::RequestConditionsSatisfied(const SavePageRequest* request) {
// If the request is expired, do not consider it.
base::TimeDelta requestAge = base::Time::Now() - request->creation_time();
- if (requestAge >
- base::TimeDelta::FromSeconds(
- policy_->GetRequestExpirationTimeInSeconds()))
+ if (requestAge > base::TimeDelta::FromSeconds(
+ policy_->GetRequestExpirationTimeInSeconds()))
return false;
// If this request is not active yet, return false.
@@ -167,10 +219,9 @@ bool RequestPicker::RequestConditionsSatisfied(const SavePageRequest* request) {
}
// Look at policies to decide which requests to prefer.
-bool RequestPicker::IsNewRequestBetter(const SavePageRequest* oldRequest,
- const SavePageRequest* newRequest,
- RequestCompareFunction comparator) {
-
+bool PickRequestTask::IsNewRequestBetter(const SavePageRequest* oldRequest,
+ const SavePageRequest* newRequest,
+ RequestCompareFunction comparator) {
// If there is no old request, the new one is better.
if (oldRequest == nullptr)
return true;
@@ -186,8 +237,9 @@ bool RequestPicker::IsNewRequestBetter(const SavePageRequest* oldRequest,
// Compare the results, checking request count before recency. Returns true if
// left hand side is better, false otherwise.
-bool RequestPicker::RetryCountFirstCompareFunction(
- const SavePageRequest* left, const SavePageRequest* right) {
+bool PickRequestTask::RetryCountFirstCompareFunction(
+ const SavePageRequest* left,
+ const SavePageRequest* right) {
// Check the attempt count.
int result = CompareRetryCount(left, right);
@@ -202,8 +254,9 @@ bool RequestPicker::RetryCountFirstCompareFunction(
// Compare the results, checking recency before request count. Returns true if
// left hand side is better, false otherwise.
-bool RequestPicker::RecencyFirstCompareFunction(
- const SavePageRequest* left, const SavePageRequest* right) {
+bool PickRequestTask::RecencyFirstCompareFunction(
+ const SavePageRequest* left,
+ const SavePageRequest* right) {
// Check the recency.
int result = CompareCreationTime(left, right);
@@ -218,14 +271,14 @@ bool RequestPicker::RecencyFirstCompareFunction(
// Compare left and right side, returning 1 if the left side is better
// (preferred by policy), 0 if the same, and -1 if the right side is better.
-int RequestPicker::CompareRetryCount(
- const SavePageRequest* left, const SavePageRequest* right) {
+int PickRequestTask::CompareRetryCount(const SavePageRequest* left,
+ const SavePageRequest* right) {
// Check the attempt count.
int result = signum(left->completed_attempt_count() -
right->completed_attempt_count());
// Flip the direction of comparison if policy prefers fewer retries.
- if (fewer_retries_better_)
+ if (policy_->ShouldPreferUntriedRequests())
result *= -1;
return result;
@@ -233,44 +286,17 @@ int RequestPicker::CompareRetryCount(
// Compare left and right side, returning 1 if the left side is better
// (preferred by policy), 0 if the same, and -1 if the right side is better.
-int RequestPicker::CompareCreationTime(
- const SavePageRequest* left, const SavePageRequest* right) {
+int PickRequestTask::CompareCreationTime(const SavePageRequest* left,
+ const SavePageRequest* right) {
// Check the recency.
base::TimeDelta difference = left->creation_time() - right->creation_time();
int result = signum(difference.InMilliseconds());
// Flip the direction of comparison if policy prefers fewer retries.
- if (earlier_requests_better_)
+ if (policy_->ShouldPreferEarlierRequests())
result *= -1;
return result;
}
-void RequestPicker::SplitRequests(
- std::vector<std::unique_ptr<SavePageRequest>> requests,
- std::vector<std::unique_ptr<SavePageRequest>>* valid_requests,
- std::vector<std::unique_ptr<SavePageRequest>>* expired_requests) {
- for (auto& request : requests) {
- if (base::Time::Now() - request->creation_time() >=
- base::TimeDelta::FromSeconds(kRequestExpirationTimeInSeconds)) {
- expired_requests->push_back(std::move(request));
- } else {
- valid_requests->push_back(std::move(request));
- }
- }
-}
-
-// Callback used after expired requests are deleted from the queue and notifies
-// the coordinator.
-void RequestPicker::OnRequestExpired(
- std::unique_ptr<UpdateRequestsResult> result) {
- const RequestCoordinator::BackgroundSavePageResult save_page_result(
- RequestCoordinator::BackgroundSavePageResult::EXPIRED);
- for (const auto& request : result->updated_items) {
- event_logger_->RecordDroppedSavePageRequest(
- request.client_id().name_space, save_page_result, request.request_id());
- notifier_->NotifyCompleted(request, save_page_result);
- }
-}
-
} // namespace offline_pages

Powered by Google App Engine
This is Rietveld 408576698