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

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

Issue 2473553004: Request Picker task (Closed)
Patch Set: CR fixes per DougArnett 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 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 <limits> 7 #include <limits>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
14 #include "base/rand_util.h" 14 #include "base/rand_util.h"
15 #include "base/sys_info.h" 15 #include "base/sys_info.h"
16 #include "base/time/time.h" 16 #include "base/time/time.h"
17 #include "components/offline_pages/background/offliner_factory.h" 17 #include "components/offline_pages/background/offliner_factory.h"
18 #include "components/offline_pages/background/offliner_policy.h" 18 #include "components/offline_pages/background/offliner_policy.h"
19 #include "components/offline_pages/background/request_picker.h"
20 #include "components/offline_pages/background/save_page_request.h" 19 #include "components/offline_pages/background/save_page_request.h"
21 #include "components/offline_pages/client_policy_controller.h" 20 #include "components/offline_pages/client_policy_controller.h"
22 #include "components/offline_pages/offline_page_item.h" 21 #include "components/offline_pages/offline_page_item.h"
23 #include "components/offline_pages/offline_page_model.h" 22 #include "components/offline_pages/offline_page_model.h"
24 23
25 namespace offline_pages { 24 namespace offline_pages {
26 25
27 namespace { 26 namespace {
28 const bool kUserRequest = true; 27 const bool kUserRequest = true;
29 const int kMinDurationSeconds = 1; 28 const int kMinDurationSeconds = 1;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // are similar. 121 // are similar.
123 int64_t GenerateOfflineId() { 122 int64_t GenerateOfflineId() {
124 return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1; 123 return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1;
125 } 124 }
126 125
127 // In case we start processing from SavePageLater, we need a callback, but there 126 // In case we start processing from SavePageLater, we need a callback, but there
128 // is nothing for it to do. 127 // is nothing for it to do.
129 void EmptySchedulerCallback(bool started) {} 128 void EmptySchedulerCallback(bool started) {}
130 129
131 // Returns whether |result| is a successful result for a single request. 130 // Returns whether |result| is a successful result for a single request.
132 bool IsSingleSuccessResult(const UpdateRequestsResult* result) { 131 bool IsSingleSuccessResult(const QueueResults::UpdateRequestsResult* result) {
133 return result->store_state == StoreState::LOADED && 132 return result->store_state == StoreState::LOADED &&
134 result->item_statuses.size() == 1 && 133 result->item_statuses.size() == 1 &&
135 result->item_statuses.at(0).second == ItemActionStatus::SUCCESS; 134 result->item_statuses.at(0).second == ItemActionStatus::SUCCESS;
136 } 135 }
137 136
138 } // namespace 137 } // namespace
139 138
140 RequestCoordinator::RequestCoordinator( 139 RequestCoordinator::RequestCoordinator(
141 std::unique_ptr<OfflinerPolicy> policy, 140 std::unique_ptr<OfflinerPolicy> policy,
142 std::unique_ptr<OfflinerFactory> factory, 141 std::unique_ptr<OfflinerFactory> factory,
(...skipping 13 matching lines...) Expand all
156 queue_(std::move(queue)), 155 queue_(std::move(queue)),
157 scheduler_(std::move(scheduler)), 156 scheduler_(std::move(scheduler)),
158 policy_controller_(new ClientPolicyController()), 157 policy_controller_(new ClientPolicyController()),
159 network_quality_estimator_(network_quality_estimator), 158 network_quality_estimator_(network_quality_estimator),
160 active_request_(nullptr), 159 active_request_(nullptr),
161 last_offlining_status_(Offliner::RequestStatus::UNKNOWN), 160 last_offlining_status_(Offliner::RequestStatus::UNKNOWN),
162 scheduler_callback_(base::Bind(&EmptySchedulerCallback)), 161 scheduler_callback_(base::Bind(&EmptySchedulerCallback)),
163 immediate_schedule_callback_(base::Bind(&EmptySchedulerCallback)), 162 immediate_schedule_callback_(base::Bind(&EmptySchedulerCallback)),
164 weak_ptr_factory_(this) { 163 weak_ptr_factory_(this) {
165 DCHECK(policy_ != nullptr); 164 DCHECK(policy_ != nullptr);
166 picker_.reset( 165 queue_->SetPickerBuilder(
167 new RequestPicker(queue_.get(), policy_.get(), this, &event_logger_)); 166 new PickRequestTaskBuilder(policy_.get(), this, &event_logger_));
168 } 167 }
169 168
170 RequestCoordinator::~RequestCoordinator() {} 169 RequestCoordinator::~RequestCoordinator() {}
171 170
172 int64_t RequestCoordinator::SavePageLater(const GURL& url, 171 int64_t RequestCoordinator::SavePageLater(const GURL& url,
173 const ClientId& client_id, 172 const ClientId& client_id,
174 bool user_requested, 173 bool user_requested,
175 RequestAvailability availability) { 174 RequestAvailability availability) {
176 DVLOG(2) << "URL is " << url << " " << __func__; 175 DVLOG(2) << "URL is " << url << " " << __func__;
177 176
(...skipping 22 matching lines...) Expand all
200 void RequestCoordinator::GetAllRequests(const GetRequestsCallback& callback) { 199 void RequestCoordinator::GetAllRequests(const GetRequestsCallback& callback) {
201 // Get all matching requests from the request queue, send them to our 200 // Get all matching requests from the request queue, send them to our
202 // callback. We bind the namespace and callback to the front of the callback 201 // callback. We bind the namespace and callback to the front of the callback
203 // param set. 202 // param set.
204 queue_->GetRequests(base::Bind(&RequestCoordinator::GetQueuedRequestsCallback, 203 queue_->GetRequests(base::Bind(&RequestCoordinator::GetQueuedRequestsCallback,
205 weak_ptr_factory_.GetWeakPtr(), callback)); 204 weak_ptr_factory_.GetWeakPtr(), callback));
206 } 205 }
207 206
208 void RequestCoordinator::GetQueuedRequestsCallback( 207 void RequestCoordinator::GetQueuedRequestsCallback(
209 const GetRequestsCallback& callback, 208 const GetRequestsCallback& callback,
210 RequestQueue::GetRequestsResult result, 209 QueueResults::GetRequestsResult result,
211 std::vector<std::unique_ptr<SavePageRequest>> requests) { 210 std::vector<std::unique_ptr<SavePageRequest>> requests) {
212 callback.Run(std::move(requests)); 211 callback.Run(std::move(requests));
213 } 212 }
214 213
215 void RequestCoordinator::StopPrerendering(Offliner::RequestStatus stop_status) { 214 void RequestCoordinator::StopPrerendering(Offliner::RequestStatus stop_status) {
216 if (offliner_ && is_busy_) { 215 if (offliner_ && is_busy_) {
217 DCHECK(active_request_.get()); 216 DCHECK(active_request_.get());
218 offliner_->Cancel(); 217 offliner_->Cancel();
219 218
220 // If we timed out, let the offliner done callback handle it. 219 // If we timed out, let the offliner done callback handle it.
(...skipping 15 matching lines...) Expand all
236 active_request_->request_id()); 235 active_request_->request_id());
237 RecordOfflinerResultUMA(active_request_->client_id(), 236 RecordOfflinerResultUMA(active_request_->client_id(),
238 active_request_->creation_time(), 237 active_request_->creation_time(),
239 last_offlining_status_); 238 last_offlining_status_);
240 is_busy_ = false; 239 is_busy_ = false;
241 active_request_.reset(); 240 active_request_.reset();
242 } 241 }
243 } 242 }
244 243
245 void RequestCoordinator::GetRequestsForSchedulingCallback( 244 void RequestCoordinator::GetRequestsForSchedulingCallback(
246 RequestQueue::GetRequestsResult result, 245 QueueResults::GetRequestsResult result,
247 std::vector<std::unique_ptr<SavePageRequest>> requests) { 246 std::vector<std::unique_ptr<SavePageRequest>> requests) {
248 bool user_requested = false; 247 bool user_requested = false;
249 248
250 // Examine all requests, if we find a user requested one, we will use the less 249 // Examine all requests, if we find a user requested one, we will use the less
251 // restrictive conditions for user_requested requests. Otherwise we will use 250 // restrictive conditions for user_requested requests. Otherwise we will use
252 // the more restrictive non-user-requested conditions. 251 // the more restrictive non-user-requested conditions.
253 for (const auto& request : requests) { 252 for (const auto& request : requests) {
254 if (request->user_requested()) { 253 if (request->user_requested()) {
255 user_requested = true; 254 user_requested = true;
256 break; 255 break;
(...skipping 17 matching lines...) Expand all
274 active_request_.reset(nullptr); 273 active_request_.reset(nullptr);
275 return true; 274 return true;
276 } 275 }
277 } 276 }
278 277
279 return false; 278 return false;
280 } 279 }
281 280
282 void RequestCoordinator::AbortRequestAttempt(SavePageRequest* request) { 281 void RequestCoordinator::AbortRequestAttempt(SavePageRequest* request) {
283 if (request->started_attempt_count() >= policy_->GetMaxStartedTries()) { 282 if (request->started_attempt_count() >= policy_->GetMaxStartedTries()) {
284 const BackgroundSavePageResult result( 283 const RequestNotifier::BackgroundSavePageResult result(
285 BackgroundSavePageResult::START_COUNT_EXCEEDED); 284 RequestNotifier::BackgroundSavePageResult::START_COUNT_EXCEEDED);
286 event_logger_.RecordDroppedSavePageRequest(request->client_id().name_space, 285 event_logger_.RecordDroppedSavePageRequest(request->client_id().name_space,
287 result, request->request_id()); 286 result, request->request_id());
288 RemoveAttemptedRequest(*request, result); 287 RemoveAttemptedRequest(*request, result);
289 } else { 288 } else {
290 queue_->MarkAttemptAborted( 289 queue_->MarkAttemptAborted(
291 request->request_id(), 290 request->request_id(),
292 base::Bind(&RequestCoordinator::MarkAttemptAbortedDone, 291 base::Bind(&RequestCoordinator::MarkAttemptAbortedDone,
293 weak_ptr_factory_.GetWeakPtr(), request->request_id(), 292 weak_ptr_factory_.GetWeakPtr(), request->request_id(),
294 request->client_id())); 293 request->client_id()));
295 } 294 }
296 } 295 }
297 296
298 void RequestCoordinator::RemoveAttemptedRequest( 297 void RequestCoordinator::RemoveAttemptedRequest(
299 const SavePageRequest& request, 298 const SavePageRequest& request,
300 BackgroundSavePageResult result) { 299 RequestNotifier::BackgroundSavePageResult result) {
301 std::vector<int64_t> remove_requests; 300 std::vector<int64_t> remove_requests;
302 remove_requests.push_back(request.request_id()); 301 remove_requests.push_back(request.request_id());
303 queue_->RemoveRequests(remove_requests, 302 queue_->RemoveRequests(remove_requests,
304 base::Bind(&RequestCoordinator::HandleRemovedRequests, 303 base::Bind(&RequestCoordinator::HandleRemovedRequests,
305 weak_ptr_factory_.GetWeakPtr(), result)); 304 weak_ptr_factory_.GetWeakPtr(), result));
306 RecordAttemptCount(request, result); 305 RecordAttemptCount(request, result);
307 } 306 }
308 307
309 void RequestCoordinator::MarkAttemptAbortedDone( 308 void RequestCoordinator::MarkAttemptAbortedDone(
310 int64_t request_id, 309 int64_t request_id,
311 const ClientId& client_id, 310 const ClientId& client_id,
312 std::unique_ptr<UpdateRequestsResult> result) { 311 std::unique_ptr<QueueResults::UpdateRequestsResult> result) {
313 // If the request succeeded, nothing to do. If it failed, we can't really do 312 // If the request succeeded, nothing to do. If it failed, we can't really do
314 // much, so just log it. 313 // much, so just log it.
315 if (!IsSingleSuccessResult(result.get())) { 314 if (!IsSingleSuccessResult(result.get())) {
316 DVLOG(1) << "Failed to mark request aborted: " << request_id; 315 DVLOG(1) << "Failed to mark request aborted: " << request_id;
317 RequestQueue::UpdateRequestResult request_result = 316 QueueResults::UpdateRequestResult request_result =
318 result->store_state != StoreState::LOADED 317 result->store_state != StoreState::LOADED
319 ? RequestQueue::UpdateRequestResult::STORE_FAILURE 318 ? QueueResults::UpdateRequestResult::STORE_FAILURE
320 : RequestQueue::UpdateRequestResult::REQUEST_DOES_NOT_EXIST; 319 : QueueResults::UpdateRequestResult::REQUEST_DOES_NOT_EXIST;
321 event_logger_.RecordUpdateRequestFailed(client_id.name_space, 320 event_logger_.RecordUpdateRequestFailed(client_id.name_space,
322 request_result); 321 request_result);
323 } 322 }
324 } 323 }
325 324
326 void RequestCoordinator::RemoveRequests( 325 void RequestCoordinator::RemoveRequests(
327 const std::vector<int64_t>& request_ids, 326 const std::vector<int64_t>& request_ids,
328 const RemoveRequestsCallback& callback) { 327 const RemoveRequestsCallback& callback) {
329 bool canceled = CancelActiveRequestIfItMatches(request_ids); 328 bool canceled = CancelActiveRequestIfItMatches(request_ids);
330 queue_->RemoveRequests( 329 queue_->RemoveRequests(
331 request_ids, 330 request_ids,
332 base::Bind(&RequestCoordinator::HandleRemovedRequestsAndCallback, 331 base::Bind(&RequestCoordinator::HandleRemovedRequestsAndCallback,
333 weak_ptr_factory_.GetWeakPtr(), callback, 332 weak_ptr_factory_.GetWeakPtr(), callback,
334 BackgroundSavePageResult::REMOVED)); 333 RequestNotifier::BackgroundSavePageResult::REMOVED));
335 if (canceled) 334 if (canceled)
336 TryNextRequest(); 335 TryNextRequest();
337 } 336 }
338 337
339 void RequestCoordinator::PauseRequests( 338 void RequestCoordinator::PauseRequests(
340 const std::vector<int64_t>& request_ids) { 339 const std::vector<int64_t>& request_ids) {
341 bool canceled = CancelActiveRequestIfItMatches(request_ids); 340 bool canceled = CancelActiveRequestIfItMatches(request_ids);
342 queue_->ChangeRequestsState( 341 queue_->ChangeRequestsState(
343 request_ids, SavePageRequest::RequestState::PAUSED, 342 request_ids, SavePageRequest::RequestState::PAUSED,
344 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback, 343 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback,
(...skipping 16 matching lines...) Expand all
361 net::NetworkChangeNotifier::ConnectionType 360 net::NetworkChangeNotifier::ConnectionType
362 RequestCoordinator::GetConnectionType() { 361 RequestCoordinator::GetConnectionType() {
363 // If we have a connection type set for test, use that. 362 // If we have a connection type set for test, use that.
364 if (use_test_connection_type_) 363 if (use_test_connection_type_)
365 return test_connection_type_; 364 return test_connection_type_;
366 365
367 return net::NetworkChangeNotifier::GetConnectionType(); 366 return net::NetworkChangeNotifier::GetConnectionType();
368 } 367 }
369 368
370 void RequestCoordinator::AddRequestResultCallback( 369 void RequestCoordinator::AddRequestResultCallback(
371 RequestQueue::AddRequestResult result, 370 QueueResults::AddRequestResult result,
372 const SavePageRequest& request) { 371 const SavePageRequest& request) {
373 NotifyAdded(request); 372 NotifyAdded(request);
374 // Inform the scheduler that we have an outstanding task. 373 // Inform the scheduler that we have an outstanding task.
375 scheduler_->Schedule(GetTriggerConditions(kUserRequest)); 374 scheduler_->Schedule(GetTriggerConditions(kUserRequest));
376 375
377 if (request.user_requested()) 376 if (request.user_requested())
378 StartImmediatelyIfConnected(); 377 StartImmediatelyIfConnected();
379 } 378 }
380 379
381 void RequestCoordinator::MarkAttemptCompletedDoneCallback( 380 void RequestCoordinator::MarkAttemptCompletedDoneCallback(
382 int64_t request_id, 381 int64_t request_id,
383 const ClientId& client_id, 382 const ClientId& client_id,
384 std::unique_ptr<UpdateRequestsResult> result) { 383 std::unique_ptr<QueueResults::UpdateRequestsResult> result) {
385 if (IsSingleSuccessResult(result.get())) { 384 if (IsSingleSuccessResult(result.get())) {
386 NotifyChanged(result->updated_items.at(0)); 385 NotifyChanged(result->updated_items.at(0));
387 } else { 386 } else {
388 DVLOG(1) << "Failed to mark request completed " << request_id; 387 DVLOG(1) << "Failed to mark request completed " << request_id;
389 RequestQueue::UpdateRequestResult request_result = 388 QueueResults::UpdateRequestResult request_result =
390 result->store_state != StoreState::LOADED 389 result->store_state != StoreState::LOADED
391 ? RequestQueue::UpdateRequestResult::STORE_FAILURE 390 ? QueueResults::UpdateRequestResult::STORE_FAILURE
392 : RequestQueue::UpdateRequestResult::REQUEST_DOES_NOT_EXIST; 391 : QueueResults::UpdateRequestResult::REQUEST_DOES_NOT_EXIST;
393 event_logger_.RecordUpdateRequestFailed(client_id.name_space, 392 event_logger_.RecordUpdateRequestFailed(client_id.name_space,
394 request_result); 393 request_result);
395 } 394 }
396 } 395 }
397 396
398 void RequestCoordinator::UpdateMultipleRequestsCallback( 397 void RequestCoordinator::UpdateMultipleRequestsCallback(
399 std::unique_ptr<UpdateRequestsResult> result) { 398 std::unique_ptr<QueueResults::UpdateRequestsResult> result) {
400 for (const auto& request : result->updated_items) 399 for (const auto& request : result->updated_items)
401 NotifyChanged(request); 400 NotifyChanged(request);
402 401
403 bool available_user_request = false; 402 bool available_user_request = false;
404 for (const auto& request : result->updated_items) { 403 for (const auto& request : result->updated_items) {
405 if (!available_user_request && request.user_requested() && 404 if (!available_user_request && request.user_requested() &&
406 request.request_state() == SavePageRequest::RequestState::AVAILABLE) { 405 request.request_state() == SavePageRequest::RequestState::AVAILABLE) {
407 available_user_request = true; 406 available_user_request = true;
408 } 407 }
409 } 408 }
410 409
411 if (available_user_request) 410 if (available_user_request)
412 StartImmediatelyIfConnected(); 411 StartImmediatelyIfConnected();
413 } 412 }
414 413
415 // When we successfully remove a request that completed successfully, move on to 414 // When we successfully remove a request that completed successfully, move on to
416 // the next request. 415 // the next request.
417 void RequestCoordinator::CompletedRequestCallback( 416 void RequestCoordinator::CompletedRequestCallback(
418 const MultipleItemStatuses& status) { 417 const MultipleItemStatuses& status) {
419 TryNextRequest(); 418 TryNextRequest();
420 } 419 }
421 420
422 void RequestCoordinator::HandleRemovedRequestsAndCallback( 421 void RequestCoordinator::HandleRemovedRequestsAndCallback(
423 const RemoveRequestsCallback& callback, 422 const RemoveRequestsCallback& callback,
424 BackgroundSavePageResult status, 423 RequestNotifier::BackgroundSavePageResult status,
425 std::unique_ptr<UpdateRequestsResult> result) { 424 std::unique_ptr<QueueResults::UpdateRequestsResult> result) {
426 // TODO(dougarnett): Define status code for user/api cancel and use here 425 // TODO(dougarnett): Define status code for user/api cancel and use here
427 // to determine whether to record cancel time UMA. 426 // to determine whether to record cancel time UMA.
428 for (const auto& request : result->updated_items) 427 for (const auto& request : result->updated_items)
429 RecordCancelTimeUMA(request); 428 RecordCancelTimeUMA(request);
430 callback.Run(result->item_statuses); 429 callback.Run(result->item_statuses);
431 HandleRemovedRequests(status, std::move(result)); 430 HandleRemovedRequests(status, std::move(result));
432 } 431 }
433 432
434 void RequestCoordinator::HandleRemovedRequests( 433 void RequestCoordinator::HandleRemovedRequests(
435 BackgroundSavePageResult status, 434 RequestNotifier::BackgroundSavePageResult status,
436 std::unique_ptr<UpdateRequestsResult> result) { 435 std::unique_ptr<QueueResults::UpdateRequestsResult> result) {
437 for (const auto& request : result->updated_items) 436 for (const auto& request : result->updated_items)
438 NotifyCompleted(request, status); 437 NotifyCompleted(request, status);
439 } 438 }
440 439
441 void RequestCoordinator::ScheduleAsNeeded() { 440 void RequestCoordinator::ScheduleAsNeeded() {
442 // Get all requests from queue (there is no filtering mechanism). 441 // Get all requests from queue (there is no filtering mechanism).
443 queue_->GetRequests( 442 queue_->GetRequests(
444 base::Bind(&RequestCoordinator::GetRequestsForSchedulingCallback, 443 base::Bind(&RequestCoordinator::GetRequestsForSchedulingCallback,
445 weak_ptr_factory_.GetWeakPtr())); 444 weak_ptr_factory_.GetWeakPtr()));
446 } 445 }
447 446
448 void RequestCoordinator::StopProcessing( 447 void RequestCoordinator::StopProcessing(
449 Offliner::RequestStatus stop_status) { 448 Offliner::RequestStatus stop_status) {
450 processing_state_ = ProcessingWindowState::STOPPED; 449 processing_state_ = ProcessingWindowState::STOPPED;
451 StopPrerendering(stop_status); 450 StopPrerendering(stop_status);
452 451
453 // Let the scheduler know we are done processing. 452 // Let the scheduler know we are done processing.
454 scheduler_callback_.Run(true); 453 scheduler_callback_.Run(true);
455 } 454 }
456 455
457 void RequestCoordinator::HandleWatchdogTimeout() { 456 void RequestCoordinator::HandleWatchdogTimeout() {
458 StopProcessing(Offliner::REQUEST_COORDINATOR_TIMED_OUT); 457 StopProcessing(Offliner::REQUEST_COORDINATOR_TIMED_OUT);
459 } 458 }
460 459
461 // Returns true if the caller should expect a callback, false otherwise. For 460 // Returns true if the caller should expect a callback, false otherwise. For
462 // instance, this would return false if a request is already in progress. 461 // instance, this would return false if a request is already in progress.
463 bool RequestCoordinator::StartProcessing( 462 bool RequestCoordinator::StartProcessing(
464 const DeviceConditions& device_conditions, 463 const DeviceConditions& device_conditions,
465 const base::Callback<void(bool)>& callback) { 464 const base::Callback<void(bool)>& callback) {
465 DVLOG(2) << "Scheduled " << __func__;
466 return StartProcessingInternal(ProcessingWindowState::SCHEDULED_WINDOW, 466 return StartProcessingInternal(ProcessingWindowState::SCHEDULED_WINDOW,
467 device_conditions, callback); 467 device_conditions, callback);
468 } 468 }
469 469
470 bool RequestCoordinator::StartProcessingInternal( 470 bool RequestCoordinator::StartProcessingInternal(
471 const ProcessingWindowState processing_state, 471 const ProcessingWindowState processing_state,
472 const DeviceConditions& device_conditions, 472 const DeviceConditions& device_conditions,
473 const base::Callback<void(bool)>& callback) { 473 const base::Callback<void(bool)>& callback) {
474 current_conditions_.reset(new DeviceConditions(device_conditions)); 474 current_conditions_.reset(new DeviceConditions(device_conditions));
475 if (is_starting_ || is_busy_) 475 if (is_starting_ || is_busy_)
(...skipping 13 matching lines...) Expand all
489 489
490 void RequestCoordinator::StartImmediatelyIfConnected() { 490 void RequestCoordinator::StartImmediatelyIfConnected() {
491 OfflinerImmediateStartStatus immediate_start_status = TryImmediateStart(); 491 OfflinerImmediateStartStatus immediate_start_status = TryImmediateStart();
492 UMA_HISTOGRAM_ENUMERATION( 492 UMA_HISTOGRAM_ENUMERATION(
493 "OfflinePages.Background.ImmediateStartStatus", immediate_start_status, 493 "OfflinePages.Background.ImmediateStartStatus", immediate_start_status,
494 RequestCoordinator::OfflinerImmediateStartStatus::STATUS_COUNT); 494 RequestCoordinator::OfflinerImmediateStartStatus::STATUS_COUNT);
495 } 495 }
496 496
497 RequestCoordinator::OfflinerImmediateStartStatus 497 RequestCoordinator::OfflinerImmediateStartStatus
498 RequestCoordinator::TryImmediateStart() { 498 RequestCoordinator::TryImmediateStart() {
499 DVLOG(2) << "Immediate " << __func__;
499 // Make sure not already busy processing. 500 // Make sure not already busy processing.
500 if (is_busy_) 501 if (is_busy_)
501 return OfflinerImmediateStartStatus::BUSY; 502 return OfflinerImmediateStartStatus::BUSY;
502 503
503 // Make sure we are not on svelte device to start immediately. 504 // Make sure we are not on svelte device to start immediately.
504 if (is_low_end_device_) { 505 if (is_low_end_device_) {
505 DVLOG(2) << "low end device, returning"; 506 DVLOG(2) << "low end device, returning";
506 // Let the scheduler know we are done processing and failed due to svelte. 507 // Let the scheduler know we are done processing and failed due to svelte.
507 immediate_schedule_callback_.Run(false); 508 immediate_schedule_callback_.Run(false);
508 return OfflinerImmediateStartStatus::NOT_STARTED_ON_SVELTE; 509 return OfflinerImmediateStartStatus::NOT_STARTED_ON_SVELTE;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 is_starting_ = false; 552 is_starting_ = false;
552 553
553 // Let the scheduler know we are done processing. 554 // Let the scheduler know we are done processing.
554 // TODO: Make sure the scheduler callback is valid before running it. 555 // TODO: Make sure the scheduler callback is valid before running it.
555 scheduler_callback_.Run(true); 556 scheduler_callback_.Run(true);
556 DVLOG(2) << " out of time, giving up. " << __func__; 557 DVLOG(2) << " out of time, giving up. " << __func__;
557 558
558 return; 559 return;
559 } 560 }
560 561
561 // Choose a request to process that meets the available conditions. 562 // Ask request queue to make a new PickRequestTask object, then put it on the
562 // This is an async call, and returns right away. 563 // task queue.
563 picker_->ChooseNextRequest(base::Bind(&RequestCoordinator::RequestPicked, 564 queue_->PickNextRequest(base::Bind(&RequestCoordinator::RequestPicked,
564 weak_ptr_factory_.GetWeakPtr()), 565 weak_ptr_factory_.GetWeakPtr()),
565 base::Bind(&RequestCoordinator::RequestNotPicked, 566 base::Bind(&RequestCoordinator::RequestNotPicked,
566 weak_ptr_factory_.GetWeakPtr()), 567 weak_ptr_factory_.GetWeakPtr()),
567 current_conditions_.get(), 568 current_conditions_.get(), disabled_requests_);
568 disabled_requests_); 569 // TODO(petewil): Verify current_conditions has a good value on all calling
570 // paths. It is really more of a "last known conditions" than "current
571 // conditions". Consider having a call to Java to check the current
572 // conditions.
569 } 573 }
570 574
571 // Called by the request picker when a request has been picked. 575 // Called by the request picker when a request has been picked.
572 void RequestCoordinator::RequestPicked(const SavePageRequest& request) { 576 void RequestCoordinator::RequestPicked(const SavePageRequest& request) {
573 DVLOG(2) << request.url() << " " << __func__; 577 DVLOG(2) << request.url() << " " << __func__;
574 is_starting_ = false; 578 is_starting_ = false;
575 579
576 // Make sure we were not stopped while picking. 580 // Make sure we were not stopped while picking.
577 if (processing_state_ != ProcessingWindowState::STOPPED) { 581 if (processing_state_ != ProcessingWindowState::STOPPED) {
578 // Send the request on to the offliner. 582 // Send the request on to the offliner.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 queue_->MarkAttemptStarted( 630 queue_->MarkAttemptStarted(
627 request.request_id(), 631 request.request_id(),
628 base::Bind(&RequestCoordinator::StartOffliner, 632 base::Bind(&RequestCoordinator::StartOffliner,
629 weak_ptr_factory_.GetWeakPtr(), request.request_id(), 633 weak_ptr_factory_.GetWeakPtr(), request.request_id(),
630 request.client_id().name_space)); 634 request.client_id().name_space));
631 } 635 }
632 636
633 void RequestCoordinator::StartOffliner( 637 void RequestCoordinator::StartOffliner(
634 int64_t request_id, 638 int64_t request_id,
635 const std::string& client_namespace, 639 const std::string& client_namespace,
636 std::unique_ptr<UpdateRequestsResult> update_result) { 640 std::unique_ptr<QueueResults::UpdateRequestsResult> update_result) {
637 if (update_result->store_state != StoreState::LOADED || 641 if (update_result->store_state != StoreState::LOADED ||
638 update_result->item_statuses.size() != 1 || 642 update_result->item_statuses.size() != 1 ||
639 update_result->item_statuses.at(0).first != request_id || 643 update_result->item_statuses.at(0).first != request_id ||
640 update_result->item_statuses.at(0).second != ItemActionStatus::SUCCESS) { 644 update_result->item_statuses.at(0).second != ItemActionStatus::SUCCESS) {
641 is_busy_ = false; 645 is_busy_ = false;
642 // TODO(fgorski): what is the best result? Do we create a new status? 646 // TODO(fgorski): what is the best result? Do we create a new status?
643 StopProcessing(Offliner::PRERENDERING_NOT_STARTED); 647 StopProcessing(Offliner::PRERENDERING_NOT_STARTED);
644 DVLOG(1) << "Failed to mark attempt started: " << request_id; 648 DVLOG(1) << "Failed to mark attempt started: " << request_id;
645 RequestQueue::UpdateRequestResult request_result = 649 QueueResults::UpdateRequestResult request_result =
646 update_result->store_state != StoreState::LOADED 650 update_result->store_state != StoreState::LOADED
647 ? RequestQueue::UpdateRequestResult::STORE_FAILURE 651 ? QueueResults::UpdateRequestResult::STORE_FAILURE
648 : RequestQueue::UpdateRequestResult::REQUEST_DOES_NOT_EXIST; 652 : QueueResults::UpdateRequestResult::REQUEST_DOES_NOT_EXIST;
649 event_logger_.RecordUpdateRequestFailed(client_namespace, request_result); 653 event_logger_.RecordUpdateRequestFailed(client_namespace, request_result);
650 return; 654 return;
651 } 655 }
652 656
653 // TODO(fgorski): Switch to request_id only, so that this value is not written 657 // TODO(fgorski): Switch to request_id only, so that this value is not written
654 // back to the store. 658 // back to the store.
655 active_request_.reset( 659 active_request_.reset(
656 new SavePageRequest(update_result->updated_items.at(0))); 660 new SavePageRequest(update_result->updated_items.at(0)));
657 661
658 // Start the load and save process in the offliner (Async). 662 // Start the load and save process in the offliner (Async).
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED || 704 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED ||
701 status == Offliner::RequestStatus::PRERENDERING_CANCELED) { 705 status == Offliner::RequestStatus::PRERENDERING_CANCELED) {
702 // Update the request for the canceled attempt. 706 // Update the request for the canceled attempt.
703 // TODO(dougarnett): See if we can conclusively identify other attempt 707 // TODO(dougarnett): See if we can conclusively identify other attempt
704 // aborted cases to treat this way (eg, for Render Process Killed). 708 // aborted cases to treat this way (eg, for Render Process Killed).
705 SavePageRequest updated_request(request); 709 SavePageRequest updated_request(request);
706 AbortRequestAttempt(&updated_request); 710 AbortRequestAttempt(&updated_request);
707 NotifyChanged(updated_request); 711 NotifyChanged(updated_request);
708 } else if (status == Offliner::RequestStatus::SAVED) { 712 } else if (status == Offliner::RequestStatus::SAVED) {
709 // Remove the request from the queue if it succeeded. 713 // Remove the request from the queue if it succeeded.
710 RemoveAttemptedRequest(request, BackgroundSavePageResult::SUCCESS); 714 RemoveAttemptedRequest(request,
715 RequestNotifier::BackgroundSavePageResult::SUCCESS);
711 } else if (status == Offliner::RequestStatus::PRERENDERING_FAILED_NO_RETRY) { 716 } else if (status == Offliner::RequestStatus::PRERENDERING_FAILED_NO_RETRY) {
712 RemoveAttemptedRequest(request, 717 RemoveAttemptedRequest(
713 BackgroundSavePageResult::PRERENDER_FAILURE); 718 request, RequestNotifier::BackgroundSavePageResult::PRERENDER_FAILURE);
714 } else if (request.completed_attempt_count() + 1 >= 719 } else if (request.completed_attempt_count() + 1 >=
715 policy_->GetMaxCompletedTries()) { 720 policy_->GetMaxCompletedTries()) {
716 // Remove from the request queue if we exceeded max retries. The +1 721 // Remove from the request queue if we exceeded max retries. The +1
717 // represents the request that just completed. Since we call 722 // represents the request that just completed. Since we call
718 // MarkAttemptCompleted within the if branches, the completed_attempt_count 723 // MarkAttemptCompleted within the if branches, the completed_attempt_count
719 // has not yet been updated when we are checking the if condition. 724 // has not yet been updated when we are checking the if condition.
720 const BackgroundSavePageResult result( 725 const RequestNotifier::BackgroundSavePageResult result(
721 BackgroundSavePageResult::RETRY_COUNT_EXCEEDED); 726 RequestNotifier::BackgroundSavePageResult::RETRY_COUNT_EXCEEDED);
722 event_logger_.RecordDroppedSavePageRequest(request.client_id().name_space, 727 event_logger_.RecordDroppedSavePageRequest(request.client_id().name_space,
723 result, request.request_id()); 728 result, request.request_id());
724 RemoveAttemptedRequest(request, result); 729 RemoveAttemptedRequest(request, result);
725 } else { 730 } else {
726 // If we failed, but are not over the limit, update the request in the 731 // If we failed, but are not over the limit, update the request in the
727 // queue. 732 // queue.
728 queue_->MarkAttemptCompleted( 733 queue_->MarkAttemptCompleted(
729 request.request_id(), 734 request.request_id(),
730 base::Bind(&RequestCoordinator::MarkAttemptCompletedDoneCallback, 735 base::Bind(&RequestCoordinator::MarkAttemptCompletedDoneCallback,
731 weak_ptr_factory_.GetWeakPtr(), request.request_id(), 736 weak_ptr_factory_.GetWeakPtr(), request.request_id(),
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 774
770 void RequestCoordinator::MarkRequestCompleted(int64_t request_id) { 775 void RequestCoordinator::MarkRequestCompleted(int64_t request_id) {
771 // Since the recent tab helper might call multiple times, ignore subsequent 776 // Since the recent tab helper might call multiple times, ignore subsequent
772 // calls for a particular request_id. 777 // calls for a particular request_id.
773 if (disabled_requests_.find(request_id) == disabled_requests_.end()) 778 if (disabled_requests_.find(request_id) == disabled_requests_.end())
774 return; 779 return;
775 disabled_requests_.erase(request_id); 780 disabled_requests_.erase(request_id);
776 781
777 // Remove the request, but send out SUCCEEDED instead of removed. 782 // Remove the request, but send out SUCCEEDED instead of removed.
778 std::vector<int64_t> request_ids { request_id }; 783 std::vector<int64_t> request_ids { request_id };
779 queue_->RemoveRequests( 784 queue_->RemoveRequests(
780 request_ids, 785 request_ids,
781 base::Bind(&RequestCoordinator::HandleRemovedRequestsAndCallback, 786 base::Bind(&RequestCoordinator::HandleRemovedRequestsAndCallback,
782 weak_ptr_factory_.GetWeakPtr(), 787 weak_ptr_factory_.GetWeakPtr(),
783 base::Bind(&RequestCoordinator::CompletedRequestCallback, 788 base::Bind(&RequestCoordinator::CompletedRequestCallback,
784 weak_ptr_factory_.GetWeakPtr()), 789 weak_ptr_factory_.GetWeakPtr()),
785 BackgroundSavePageResult::SUCCESS)); 790 RequestNotifier::BackgroundSavePageResult::SUCCESS));
786 } 791 }
787 792
788 const Scheduler::TriggerConditions RequestCoordinator::GetTriggerConditions( 793 const Scheduler::TriggerConditions RequestCoordinator::GetTriggerConditions(
789 const bool user_requested) { 794 const bool user_requested) {
790 return Scheduler::TriggerConditions( 795 return Scheduler::TriggerConditions(
791 policy_->PowerRequired(user_requested), 796 policy_->PowerRequired(user_requested),
792 policy_->BatteryPercentageRequired(user_requested), 797 policy_->BatteryPercentageRequired(user_requested),
793 policy_->UnmeteredNetworkRequired(user_requested)); 798 policy_->UnmeteredNetworkRequired(user_requested));
794 } 799 }
795 800
796 void RequestCoordinator::AddObserver(Observer* observer) { 801 void RequestCoordinator::AddObserver(Observer* observer) {
797 DCHECK(observer); 802 DCHECK(observer);
798 observers_.AddObserver(observer); 803 observers_.AddObserver(observer);
799 } 804 }
800 805
801 void RequestCoordinator::RemoveObserver(Observer* observer) { 806 void RequestCoordinator::RemoveObserver(Observer* observer) {
802 observers_.RemoveObserver(observer); 807 observers_.RemoveObserver(observer);
803 } 808 }
804 809
805 void RequestCoordinator::NotifyAdded(const SavePageRequest& request) { 810 void RequestCoordinator::NotifyAdded(const SavePageRequest& request) {
806 for (Observer& observer : observers_) 811 for (Observer& observer : observers_)
807 observer.OnAdded(request); 812 observer.OnAdded(request);
808 } 813 }
809 814
810 void RequestCoordinator::NotifyCompleted(const SavePageRequest& request, 815 void RequestCoordinator::NotifyCompleted(
811 BackgroundSavePageResult status) { 816 const SavePageRequest& request,
817 RequestNotifier::BackgroundSavePageResult status) {
812 for (Observer& observer : observers_) 818 for (Observer& observer : observers_)
813 observer.OnCompleted(request, status); 819 observer.OnCompleted(request, status);
814 } 820 }
815 821
816 void RequestCoordinator::NotifyChanged(const SavePageRequest& request) { 822 void RequestCoordinator::NotifyChanged(const SavePageRequest& request) {
817 for (Observer& observer : observers_) 823 for (Observer& observer : observers_)
818 observer.OnChanged(request); 824 observer.OnChanged(request);
819 } 825 }
820 826
821 void RequestCoordinator::GetOffliner() { 827 void RequestCoordinator::GetOffliner() {
822 if (!offliner_) { 828 if (!offliner_) {
823 offliner_ = factory_->GetOffliner(policy_.get()); 829 offliner_ = factory_->GetOffliner(policy_.get());
824 } 830 }
825 } 831 }
826 832
827 ClientPolicyController* RequestCoordinator::GetPolicyController() { 833 ClientPolicyController* RequestCoordinator::GetPolicyController() {
828 return policy_controller_.get(); 834 return policy_controller_.get();
829 } 835 }
830 836
831 void RequestCoordinator::Shutdown() { 837 void RequestCoordinator::Shutdown() {
832 network_quality_estimator_ = nullptr; 838 network_quality_estimator_ = nullptr;
833 } 839 }
834 840
835 } // namespace offline_pages 841 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698