| 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/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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |