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

Side by Side Diff: components/offline_pages/background/request_coordinator.cc

Issue 2269173003: Adjust scheduling for non-user requested items (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Tests written and working. Created 4 years, 3 months 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
OLDNEW
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_coordinator.h" 5 #include "components/offline_pages/background/request_coordinator.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/metrics/histogram_macros.h" 12 #include "base/metrics/histogram_macros.h"
13 #include "base/rand_util.h" 13 #include "base/rand_util.h"
14 #include "base/time/time.h" 14 #include "base/time/time.h"
15 #include "components/offline_pages/background/offliner_factory.h" 15 #include "components/offline_pages/background/offliner_factory.h"
16 #include "components/offline_pages/background/offliner_policy.h" 16 #include "components/offline_pages/background/offliner_policy.h"
17 #include "components/offline_pages/background/request_picker.h" 17 #include "components/offline_pages/background/request_picker.h"
18 #include "components/offline_pages/background/save_page_request.h" 18 #include "components/offline_pages/background/save_page_request.h"
19 #include "components/offline_pages/offline_page_item.h" 19 #include "components/offline_pages/offline_page_item.h"
20 #include "components/offline_pages/offline_page_model.h" 20 #include "components/offline_pages/offline_page_model.h"
21 21
22 namespace offline_pages { 22 namespace offline_pages {
23 23
24 namespace { 24 namespace {
25 const bool kUserRequest = true;
25 26
26 // Records the final request status UMA for an offlining request. This should 27 // Records the final request status UMA for an offlining request. This should
27 // only be called once per Offliner::LoadAndSave request. 28 // only be called once per Offliner::LoadAndSave request.
28 void RecordOfflinerResultUMA(const ClientId& client_id, 29 void RecordOfflinerResultUMA(const ClientId& client_id,
29 Offliner::RequestStatus request_status) { 30 Offliner::RequestStatus request_status) {
30 // TODO(dougarnett): Consider exposing AddHistogramSuffix from 31 // TODO(dougarnett): Consider exposing AddHistogramSuffix from
31 // offline_page_model_impl.cc as visible utility method. 32 // offline_page_model_impl.cc as visible utility method.
32 std::string histogram_name("OfflinePages.Background.OfflinerRequestStatus"); 33 std::string histogram_name("OfflinePages.Background.OfflinerRequestStatus");
33 if (!client_id.name_space.empty()) { 34 if (!client_id.name_space.empty()) {
34 histogram_name += "." + client_id.name_space; 35 histogram_name += "." + client_id.name_space;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED; 129 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED;
129 130
130 if (active_request_) { 131 if (active_request_) {
131 RecordOfflinerResultUMA(active_request_->client_id(), 132 RecordOfflinerResultUMA(active_request_->client_id(),
132 last_offlining_status_); 133 last_offlining_status_);
133 active_request_.reset(); 134 active_request_.reset();
134 } 135 }
135 136
136 } 137 }
137 138
139 void RequestCoordinator::GetRequestsForSchedulingCallback(
140 RequestQueue::GetRequestsResult result,
141 const std::vector<SavePageRequest>& requests) {
142 bool user_requested = false;
143
144 // Examine all requests, if we find a user requested one, we will use the less
145 // restrictive conditions for user_requested requests. Otherwise we will use
146 // the more restrictive non-user-requested conditions.
147 for (const SavePageRequest& request : requests) {
148 if (request.user_requested()) {
149 user_requested = true;
150 break;
151 }
152 }
153
154 // In the get callback, determine the least restrictive, and call
155 // GetTriggerConditions based on that.
156 scheduler_->Schedule(GetTriggerConditions(user_requested));
157 }
158
138 bool RequestCoordinator::CancelActiveRequestIfItMatches( 159 bool RequestCoordinator::CancelActiveRequestIfItMatches(
139 const std::vector<int64_t>& request_ids) { 160 const std::vector<int64_t>& request_ids) {
140 // If we have a request in progress and need to cancel it, call the 161 // If we have a request in progress and need to cancel it, call the
141 // pre-renderer to cancel. TODO Make sure we remove any page created by the 162 // pre-renderer to cancel. TODO Make sure we remove any page created by the
142 // prerenderer if it doesn't get the cancel in time. 163 // prerenderer if it doesn't get the cancel in time.
143 if (active_request_ != nullptr) { 164 if (active_request_ != nullptr) {
144 if (request_ids.end() != std::find(request_ids.begin(), request_ids.end(), 165 if (request_ids.end() != std::find(request_ids.begin(), request_ids.end(),
145 active_request_->request_id())) { 166 active_request_->request_id())) {
146 StopPrerendering(); 167 StopPrerendering();
147 return true; 168 return true;
(...skipping 26 matching lines...) Expand all
174 if (canceled) 195 if (canceled)
175 TryNextRequest(); 196 TryNextRequest();
176 } 197 }
177 198
178 void RequestCoordinator::ResumeRequests( 199 void RequestCoordinator::ResumeRequests(
179 const std::vector<int64_t>& request_ids) { 200 const std::vector<int64_t>& request_ids) {
180 queue_->ChangeRequestsState( 201 queue_->ChangeRequestsState(
181 request_ids, SavePageRequest::RequestState::AVAILABLE, 202 request_ids, SavePageRequest::RequestState::AVAILABLE,
182 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback, 203 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback,
183 weak_ptr_factory_.GetWeakPtr())); 204 weak_ptr_factory_.GetWeakPtr()));
184 // TODO: Should we also schedule a task, in case there is not one scheduled? 205 // Schedule a task, in case there is not one scheduled.
206 ScheduleAsNeeded();
185 } 207 }
186 208
187 void RequestCoordinator::AddRequestResultCallback( 209 void RequestCoordinator::AddRequestResultCallback(
188 RequestQueue::AddRequestResult result, 210 RequestQueue::AddRequestResult result,
189 const SavePageRequest& request) { 211 const SavePageRequest& request) {
190 // Inform the scheduler that we have an outstanding task.. 212 // Inform the scheduler that we have an outstanding task..
191 scheduler_->Schedule(GetTriggerConditionsForUserRequest()); 213 ScheduleAsNeeded();
192 } 214 }
193 215
194 // Called in response to updating a request in the request queue. 216 // Called in response to updating a request in the request queue.
195 void RequestCoordinator::UpdateRequestCallback( 217 void RequestCoordinator::UpdateRequestCallback(
196 const ClientId& client_id, 218 const ClientId& client_id,
197 RequestQueue::UpdateRequestResult result) { 219 RequestQueue::UpdateRequestResult result) {
198 // If the request succeeded, nothing to do. If it failed, we can't really do 220 // If the request succeeded, nothing to do. If it failed, we can't really do
199 // much, so just log it. 221 // much, so just log it.
200 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { 222 if (result != RequestQueue::UpdateRequestResult::SUCCESS) {
201 DVLOG(1) << "Failed to update request attempt details. " 223 DVLOG(1) << "Failed to update request attempt details. "
(...skipping 18 matching lines...) Expand all
220 HandleRemovedRequests(results, requests); 242 HandleRemovedRequests(results, requests);
221 } 243 }
222 244
223 void RequestCoordinator::HandleRemovedRequests( 245 void RequestCoordinator::HandleRemovedRequests(
224 const RequestQueue::UpdateMultipleRequestResults& results, 246 const RequestQueue::UpdateMultipleRequestResults& results,
225 const std::vector<SavePageRequest>& requests) { 247 const std::vector<SavePageRequest>& requests) {
226 for (SavePageRequest request : requests) 248 for (SavePageRequest request : requests)
227 NotifyCompleted(request, SavePageStatus::REMOVED); 249 NotifyCompleted(request, SavePageStatus::REMOVED);
228 } 250 }
229 251
252 void RequestCoordinator::ScheduleAsNeeded() {
253 // Get all requests from queue (there is no filtering mechanism).
254 queue_->GetRequests(
255 base::Bind(&RequestCoordinator::GetRequestsForSchedulingCallback,
256 weak_ptr_factory_.GetWeakPtr()));
257 }
258
230 void RequestCoordinator::StopProcessing() { 259 void RequestCoordinator::StopProcessing() {
231 is_stopped_ = true; 260 is_stopped_ = true;
232 StopPrerendering(); 261 StopPrerendering();
233 262
234 // Let the scheduler know we are done processing. 263 // Let the scheduler know we are done processing.
235 scheduler_callback_.Run(true); 264 scheduler_callback_.Run(true);
236 } 265 }
237 266
238 // Returns true if the caller should expect a callback, false otherwise. For 267 // Returns true if the caller should expect a callback, false otherwise. For
239 // instance, this would return false if a request is already in progress. 268 // instance, this would return false if a request is already in progress.
(...skipping 24 matching lines...) Expand all
264 base::TimeDelta::FromSeconds( 293 base::TimeDelta::FromSeconds(
265 policy_->GetBackgroundProcessingTimeBudgetSeconds())) { 294 policy_->GetBackgroundProcessingTimeBudgetSeconds())) {
266 // Let the scheduler know we are done processing. 295 // Let the scheduler know we are done processing.
267 scheduler_callback_.Run(true); 296 scheduler_callback_.Run(true);
268 297
269 return; 298 return;
270 } 299 }
271 300
272 // Choose a request to process that meets the available conditions. 301 // Choose a request to process that meets the available conditions.
273 // This is an async call, and returns right away. 302 // This is an async call, and returns right away.
274 picker_->ChooseNextRequest( 303 picker_->ChooseNextRequest(base::Bind(&RequestCoordinator::RequestPicked,
275 base::Bind(&RequestCoordinator::RequestPicked, 304 weak_ptr_factory_.GetWeakPtr()),
276 weak_ptr_factory_.GetWeakPtr()), 305 base::Bind(&RequestCoordinator::RequestNotPicked,
277 base::Bind(&RequestCoordinator::RequestQueueEmpty, 306 weak_ptr_factory_.GetWeakPtr()),
278 weak_ptr_factory_.GetWeakPtr()), 307 current_conditions_.get());
279 current_conditions_.get());
280 } 308 }
281 309
282 // Called by the request picker when a request has been picked. 310 // Called by the request picker when a request has been picked.
283 void RequestCoordinator::RequestPicked(const SavePageRequest& request) { 311 void RequestCoordinator::RequestPicked(const SavePageRequest& request) {
284 // Send the request on to the offliner. 312 // Send the request on to the offliner.
285 SendRequestToOffliner(request); 313 SendRequestToOffliner(request);
286 } 314 }
287 315
288 void RequestCoordinator::RequestQueueEmpty() { 316 void RequestCoordinator::RequestNotPicked(
317 bool non_user_requested_tasks_remaining) {
289 // Clear the outstanding "safety" task in the scheduler. 318 // Clear the outstanding "safety" task in the scheduler.
290 scheduler_->Unschedule(); 319 scheduler_->Unschedule();
320
321 if (non_user_requested_tasks_remaining)
322 scheduler_->Schedule(GetTriggerConditions(!kUserRequest));
291 // Let the scheduler know we are done processing. 323 // Let the scheduler know we are done processing.
292 scheduler_callback_.Run(true); 324 scheduler_callback_.Run(true);
293 } 325 }
294 326
295 void RequestCoordinator::SendRequestToOffliner(const SavePageRequest& request) { 327 void RequestCoordinator::SendRequestToOffliner(const SavePageRequest& request) {
296 // Check that offlining didn't get cancelled while performing some async 328 // Check that offlining didn't get cancelled while performing some async
297 // steps. 329 // steps.
298 if (is_stopped_) 330 if (is_stopped_)
299 return; 331 return;
300 332
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 case Offliner::RequestStatus::PRERENDERING_FAILED: 442 case Offliner::RequestStatus::PRERENDERING_FAILED:
411 // No further processing in this service window. 443 // No further processing in this service window.
412 break; 444 break;
413 default: 445 default:
414 // Make explicit choice about new status codes that actually reach here. 446 // Make explicit choice about new status codes that actually reach here.
415 // Their default is no further processing in this service window. 447 // Their default is no further processing in this service window.
416 DCHECK(false); 448 DCHECK(false);
417 } 449 }
418 } 450 }
419 451
420 const Scheduler::TriggerConditions 452 const Scheduler::TriggerConditions RequestCoordinator::GetTriggerConditions(
421 RequestCoordinator::GetTriggerConditionsForUserRequest() { 453 const bool user_requested) {
422 Scheduler::TriggerConditions trigger_conditions( 454 return Scheduler::TriggerConditions(
423 policy_->PowerRequiredForUserRequestedPage(), 455 policy_->PowerRequired(user_requested),
424 policy_->BatteryPercentageRequiredForUserRequestedPage(), 456 policy_->BatteryPercentageRequired(user_requested),
425 policy_->UnmeteredNetworkRequiredForUserRequestedPage()); 457 policy_->UnmeteredNetworkRequired(user_requested));
426 return trigger_conditions;
427 } 458 }
428 459
429 void RequestCoordinator::AddObserver(Observer* observer) { 460 void RequestCoordinator::AddObserver(Observer* observer) {
430 DCHECK(observer); 461 DCHECK(observer);
431 observers_.AddObserver(observer); 462 observers_.AddObserver(observer);
432 } 463 }
433 464
434 void RequestCoordinator::RemoveObserver(Observer* observer) { 465 void RequestCoordinator::RemoveObserver(Observer* observer) {
435 observers_.RemoveObserver(observer); 466 observers_.RemoveObserver(observer);
436 } 467 }
(...skipping 11 matching lines...) Expand all
448 FOR_EACH_OBSERVER(Observer, observers_, OnChanged(request)); 479 FOR_EACH_OBSERVER(Observer, observers_, OnChanged(request));
449 } 480 }
450 481
451 void RequestCoordinator::GetOffliner() { 482 void RequestCoordinator::GetOffliner() {
452 if (!offliner_) { 483 if (!offliner_) {
453 offliner_ = factory_->GetOffliner(policy_.get()); 484 offliner_ = factory_->GetOffliner(policy_.get());
454 } 485 }
455 } 486 }
456 487
457 } // namespace offline_pages 488 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698