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

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

Issue 2493683002: [OfflinePages] Fixes RequestCoordinator bug not clearing state on timeout (Closed)
Patch Set: Merge 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"
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 GetRequestsResult result, 235 GetRequestsResult result,
236 std::vector<std::unique_ptr<SavePageRequest>> requests) { 236 std::vector<std::unique_ptr<SavePageRequest>> requests) {
237 callback.Run(std::move(requests)); 237 callback.Run(std::move(requests));
238 } 238 }
239 239
240 void RequestCoordinator::StopPrerendering(Offliner::RequestStatus stop_status) { 240 void RequestCoordinator::StopPrerendering(Offliner::RequestStatus stop_status) {
241 if (offliner_ && is_busy_) { 241 if (offliner_ && is_busy_) {
242 DCHECK(active_request_.get()); 242 DCHECK(active_request_.get());
243 offliner_->Cancel(); 243 offliner_->Cancel();
244 244
245 // If we timed out, let the offliner done callback handle it. 245 if (stop_status == Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT) {
246 if (stop_status == Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT) 246 // Consider watchdog timeout a completed attempt.
247 return; 247 SavePageRequest request(*active_request_.get());
248 248 UpdateRequestForCompletedAttempt(request,
249 // Otherwise, this attempt never really had a chance to run, mark it 249 Offliner::REQUEST_COORDINATOR_TIMED_OUT);
250 // aborted. 250 } else {
251 AbortRequestAttempt(*active_request_.get()); 251 // Otherwise consider this stop an aborted attempt.
252 UpdateRequestForAbortedAttempt(*active_request_.get());
253 }
252 } 254 }
253 255
254 // Stopping offliner means it will not call callback so set last status. 256 // Stopping offliner means it will not call callback so set last status.
255 last_offlining_status_ = stop_status; 257 last_offlining_status_ = stop_status;
256 258
257 if (active_request_) { 259 if (active_request_) {
258 event_logger_.RecordOfflinerResult(active_request_->client_id().name_space, 260 event_logger_.RecordOfflinerResult(active_request_->client_id().name_space,
259 last_offlining_status_, 261 last_offlining_status_,
260 active_request_->request_id()); 262 active_request_->request_id());
261 RecordOfflinerResultUMA(active_request_->client_id(), 263 RecordOfflinerResultUMA(active_request_->client_id(),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 active_request_->request_id())) { 298 active_request_->request_id())) {
297 StopPrerendering(Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED); 299 StopPrerendering(Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED);
298 active_request_.reset(nullptr); 300 active_request_.reset(nullptr);
299 return true; 301 return true;
300 } 302 }
301 } 303 }
302 304
303 return false; 305 return false;
304 } 306 }
305 307
306 void RequestCoordinator::AbortRequestAttempt(const SavePageRequest& request) { 308 void RequestCoordinator::UpdateRequestForAbortedAttempt(
309 const SavePageRequest& request) {
307 if (request.started_attempt_count() >= policy_->GetMaxStartedTries()) { 310 if (request.started_attempt_count() >= policy_->GetMaxStartedTries()) {
308 const RequestNotifier::BackgroundSavePageResult result( 311 const RequestNotifier::BackgroundSavePageResult result(
309 RequestNotifier::BackgroundSavePageResult::START_COUNT_EXCEEDED); 312 RequestNotifier::BackgroundSavePageResult::START_COUNT_EXCEEDED);
310 event_logger_.RecordDroppedSavePageRequest(request.client_id().name_space, 313 event_logger_.RecordDroppedSavePageRequest(request.client_id().name_space,
311 result, request.request_id()); 314 result, request.request_id());
312 RemoveAttemptedRequest(request, result); 315 RemoveAttemptedRequest(request, result);
313 } else { 316 } else {
314 queue_->MarkAttemptAborted( 317 queue_->MarkAttemptAborted(
315 request.request_id(), 318 request.request_id(),
316 base::Bind(&RequestCoordinator::MarkAttemptAbortedDone, 319 base::Bind(&RequestCoordinator::MarkAttemptAbortedDone,
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 void RequestCoordinator::StopProcessing( 503 void RequestCoordinator::StopProcessing(
501 Offliner::RequestStatus stop_status) { 504 Offliner::RequestStatus stop_status) {
502 processing_state_ = ProcessingWindowState::STOPPED; 505 processing_state_ = ProcessingWindowState::STOPPED;
503 StopPrerendering(stop_status); 506 StopPrerendering(stop_status);
504 507
505 // Let the scheduler know we are done processing. 508 // Let the scheduler know we are done processing.
506 scheduler_callback_.Run(true); 509 scheduler_callback_.Run(true);
507 } 510 }
508 511
509 void RequestCoordinator::HandleWatchdogTimeout() { 512 void RequestCoordinator::HandleWatchdogTimeout() {
510 StopProcessing(Offliner::REQUEST_COORDINATOR_TIMED_OUT); 513 Offliner::RequestStatus watchdog_status =
514 Offliner::REQUEST_COORDINATOR_TIMED_OUT;
515 StopPrerendering(watchdog_status);
516 TryNextRequest();
511 } 517 }
512 518
513 // Returns true if the caller should expect a callback, false otherwise. For 519 // Returns true if the caller should expect a callback, false otherwise. For
514 // instance, this would return false if a request is already in progress. 520 // instance, this would return false if a request is already in progress.
515 bool RequestCoordinator::StartProcessing( 521 bool RequestCoordinator::StartProcessing(
516 const DeviceConditions& device_conditions, 522 const DeviceConditions& device_conditions,
517 const base::Callback<void(bool)>& callback) { 523 const base::Callback<void(bool)>& callback) {
518 DVLOG(2) << "Scheduled " << __func__; 524 DVLOG(2) << "Scheduled " << __func__;
519 return StartProcessingInternal(ProcessingWindowState::SCHEDULED_WINDOW, 525 return StartProcessingInternal(ProcessingWindowState::SCHEDULED_WINDOW,
520 device_conditions, callback); 526 device_conditions, callback);
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 << (status == Offliner::RequestStatus::SAVED) 747 << (status == Offliner::RequestStatus::SAVED)
742 << ", status: " << static_cast<int>(status) << ", " << __func__; 748 << ", status: " << static_cast<int>(status) << ", " << __func__;
743 DCHECK_NE(status, Offliner::RequestStatus::UNKNOWN); 749 DCHECK_NE(status, Offliner::RequestStatus::UNKNOWN);
744 DCHECK_NE(status, Offliner::RequestStatus::LOADED); 750 DCHECK_NE(status, Offliner::RequestStatus::LOADED);
745 event_logger_.RecordOfflinerResult(request.client_id().name_space, status, 751 event_logger_.RecordOfflinerResult(request.client_id().name_space, status,
746 request.request_id()); 752 request.request_id());
747 last_offlining_status_ = status; 753 last_offlining_status_ = status;
748 RecordOfflinerResultUMA(request.client_id(), request.creation_time(), 754 RecordOfflinerResultUMA(request.client_id(), request.creation_time(),
749 last_offlining_status_); 755 last_offlining_status_);
750 watchdog_timer_.Stop(); 756 watchdog_timer_.Stop();
751
752 is_busy_ = false; 757 is_busy_ = false;
753 active_request_.reset(nullptr); 758 active_request_.reset(nullptr);
754 759
760 UpdateRequestForCompletedAttempt(request, status);
761 if (ShouldTryNextRequest(status))
762 TryNextRequest();
763 else
764 scheduler_callback_.Run(true);
765 }
766
767 void RequestCoordinator::UpdateRequestForCompletedAttempt(
768 const SavePageRequest& request,
769 Offliner::RequestStatus status) {
755 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED || 770 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED ||
756 status == Offliner::RequestStatus::PRERENDERING_CANCELED) { 771 status == Offliner::RequestStatus::PRERENDERING_CANCELED) {
757 // Update the request for the canceled attempt. 772 // Update the request for the canceled attempt.
758 // TODO(dougarnett): See if we can conclusively identify other attempt 773 // TODO(dougarnett): See if we can conclusively identify other attempt
759 // aborted cases to treat this way (eg, for Render Process Killed). 774 // aborted cases to treat this way (eg, for Render Process Killed).
760 AbortRequestAttempt(request); 775 UpdateRequestForAbortedAttempt(request);
761 } else if (status == Offliner::RequestStatus::SAVED) { 776 } else if (status == Offliner::RequestStatus::SAVED) {
762 // Remove the request from the queue if it succeeded. 777 // Remove the request from the queue if it succeeded.
763 RemoveAttemptedRequest(request, 778 RemoveAttemptedRequest(request,
764 RequestNotifier::BackgroundSavePageResult::SUCCESS); 779 RequestNotifier::BackgroundSavePageResult::SUCCESS);
765 } else if (status == Offliner::RequestStatus::PRERENDERING_FAILED_NO_RETRY) { 780 } else if (status == Offliner::RequestStatus::PRERENDERING_FAILED_NO_RETRY) {
766 RemoveAttemptedRequest( 781 RemoveAttemptedRequest(
767 request, RequestNotifier::BackgroundSavePageResult::PRERENDER_FAILURE); 782 request, RequestNotifier::BackgroundSavePageResult::PRERENDER_FAILURE);
768 } else if (request.completed_attempt_count() + 1 >= 783 } else if (request.completed_attempt_count() + 1 >=
769 policy_->GetMaxCompletedTries()) { 784 policy_->GetMaxCompletedTries()) {
770 // Remove from the request queue if we exceeded max retries. The +1 785 // Remove from the request queue if we exceeded max retries. The +1
771 // represents the request that just completed. Since we call 786 // represents the request that just completed. Since we call
772 // MarkAttemptCompleted within the if branches, the completed_attempt_count 787 // MarkAttemptCompleted within the if branches, the completed_attempt_count
773 // has not yet been updated when we are checking the if condition. 788 // has not yet been updated when we are checking the if condition.
774 const RequestNotifier::BackgroundSavePageResult result( 789 const RequestNotifier::BackgroundSavePageResult result(
775 RequestNotifier::BackgroundSavePageResult::RETRY_COUNT_EXCEEDED); 790 RequestNotifier::BackgroundSavePageResult::RETRY_COUNT_EXCEEDED);
776 event_logger_.RecordDroppedSavePageRequest(request.client_id().name_space, 791 event_logger_.RecordDroppedSavePageRequest(request.client_id().name_space,
777 result, request.request_id()); 792 result, request.request_id());
778 RemoveAttemptedRequest(request, result); 793 RemoveAttemptedRequest(request, result);
779 } else { 794 } else {
780 // If we failed, but are not over the limit, update the request in the 795 // If we failed, but are not over the limit, update the request in the
781 // queue. 796 // queue.
782 queue_->MarkAttemptCompleted( 797 queue_->MarkAttemptCompleted(
783 request.request_id(), 798 request.request_id(),
784 base::Bind(&RequestCoordinator::MarkAttemptCompletedDoneCallback, 799 base::Bind(&RequestCoordinator::MarkAttemptCompletedDoneCallback,
785 weak_ptr_factory_.GetWeakPtr(), request.request_id(), 800 weak_ptr_factory_.GetWeakPtr(), request.request_id(),
786 request.client_id())); 801 request.client_id()));
787 } 802 }
803 }
788 804
789 // Determine whether we might try another request in this 805 bool RequestCoordinator::ShouldTryNextRequest(
790 // processing window based on how the previous request completed. 806 Offliner::RequestStatus previous_request_status) {
791 switch (status) { 807 switch (previous_request_status) {
792 case Offliner::RequestStatus::SAVED: 808 case Offliner::RequestStatus::SAVED:
793 case Offliner::RequestStatus::SAVE_FAILED: 809 case Offliner::RequestStatus::SAVE_FAILED:
794 case Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED: 810 case Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED:
795 case Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT: 811 case Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT:
796 case Offliner::RequestStatus::PRERENDERING_FAILED_NO_RETRY: 812 case Offliner::RequestStatus::PRERENDERING_FAILED_NO_RETRY:
797 // Consider processing another request in this service window. 813 return true;
798 TryNextRequest();
799 break;
800 case Offliner::RequestStatus::FOREGROUND_CANCELED: 814 case Offliner::RequestStatus::FOREGROUND_CANCELED:
801 case Offliner::RequestStatus::PRERENDERING_CANCELED: 815 case Offliner::RequestStatus::PRERENDERING_CANCELED:
802 case Offliner::RequestStatus::PRERENDERING_FAILED: 816 case Offliner::RequestStatus::PRERENDERING_FAILED:
803 // No further processing in this service window. 817 // No further processing in this service window.
804 // Let the scheduler know we are done processing. 818 return false;
805 scheduler_callback_.Run(true);
806 break;
807 default: 819 default:
808 // Make explicit choice about new status codes that actually reach here. 820 // Make explicit choice about new status codes that actually reach here.
809 // Their default is no further processing in this service window. 821 // Their default is no further processing in this service window.
810 NOTREACHED(); 822 NOTREACHED();
823 return false;
811 } 824 }
812 } 825 }
813 826
814 void RequestCoordinator::EnableForOffliner(int64_t request_id) { 827 void RequestCoordinator::EnableForOffliner(int64_t request_id) {
815 // Since the recent tab helper might call multiple times, ignore subsequent 828 // Since the recent tab helper might call multiple times, ignore subsequent
816 // calls for a particular request_id. 829 // calls for a particular request_id.
817 if (disabled_requests_.find(request_id) == disabled_requests_.end()) 830 if (disabled_requests_.find(request_id) == disabled_requests_.end())
818 return; 831 return;
819 disabled_requests_.erase(request_id); 832 disabled_requests_.erase(request_id);
820 // If we are not busy, start processing right away. 833 // If we are not busy, start processing right away.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 894
882 ClientPolicyController* RequestCoordinator::GetPolicyController() { 895 ClientPolicyController* RequestCoordinator::GetPolicyController() {
883 return policy_controller_.get(); 896 return policy_controller_.get();
884 } 897 }
885 898
886 void RequestCoordinator::Shutdown() { 899 void RequestCoordinator::Shutdown() {
887 network_quality_estimator_ = nullptr; 900 network_quality_estimator_ = nullptr;
888 } 901 }
889 902
890 } // namespace offline_pages 903 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698