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