| 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 <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" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 // macro adapted to allow for a dynamically suffixed histogram name. | 38 // macro adapted to allow for a dynamically suffixed histogram name. |
| 39 // Note: The factory creates and owns the histogram. | 39 // Note: The factory creates and owns the histogram. |
| 40 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( | 40 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( |
| 41 histogram_name, 1, | 41 histogram_name, 1, |
| 42 static_cast<int>(Offliner::RequestStatus::STATUS_COUNT), | 42 static_cast<int>(Offliner::RequestStatus::STATUS_COUNT), |
| 43 static_cast<int>(Offliner::RequestStatus::STATUS_COUNT) + 1, | 43 static_cast<int>(Offliner::RequestStatus::STATUS_COUNT) + 1, |
| 44 base::HistogramBase::kUmaTargetedHistogramFlag); | 44 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 45 histogram->Add(static_cast<int>(request_status)); | 45 histogram->Add(static_cast<int>(request_status)); |
| 46 } | 46 } |
| 47 | 47 |
| 48 // Records the number of started attempts for completed requests (whether |
| 49 // successful or not). |
| 50 void RecordAttemptCount(const SavePageRequest& request, |
| 51 RequestNotifier::SavePageStatus status) { |
| 52 if (status == RequestNotifier::SavePageStatus::SUCCESS) { |
| 53 // TODO(dougarnett): Also record UMA for completed attempts here. |
| 54 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 55 "OfflinePages.Background.RequestSuccess.StartedAttemptCount", |
| 56 request.started_attempt_count(), 1, 10, 11); |
| 57 } else { |
| 58 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 59 "OfflinePages.Background.RequestFailure.StartedAttemptCount", |
| 60 request.started_attempt_count(), 1, 10, 11); |
| 61 } |
| 62 } |
| 63 |
| 48 // This should use the same algorithm as we use for OfflinePageItem, so the IDs | 64 // This should use the same algorithm as we use for OfflinePageItem, so the IDs |
| 49 // are similar. | 65 // are similar. |
| 50 int64_t GenerateOfflineId() { | 66 int64_t GenerateOfflineId() { |
| 51 return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1; | 67 return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1; |
| 52 } | 68 } |
| 53 | 69 |
| 54 // In case we start processing from SavePageLater, we need a callback, but there | 70 // In case we start processing from SavePageLater, we need a callback, but there |
| 55 // is nothing for it to do. | 71 // is nothing for it to do. |
| 56 void EmptySchedulerCallback(bool started) {} | 72 void EmptySchedulerCallback(bool started) {} |
| 57 | 73 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 | 128 |
| 113 void RequestCoordinator::GetQueuedRequestsCallback( | 129 void RequestCoordinator::GetQueuedRequestsCallback( |
| 114 const GetRequestsCallback& callback, | 130 const GetRequestsCallback& callback, |
| 115 RequestQueue::GetRequestsResult result, | 131 RequestQueue::GetRequestsResult result, |
| 116 const std::vector<SavePageRequest>& requests) { | 132 const std::vector<SavePageRequest>& requests) { |
| 117 callback.Run(requests); | 133 callback.Run(requests); |
| 118 } | 134 } |
| 119 | 135 |
| 120 void RequestCoordinator::StopPrerendering() { | 136 void RequestCoordinator::StopPrerendering() { |
| 121 if (offliner_ && is_busy_) { | 137 if (offliner_ && is_busy_) { |
| 138 DCHECK(active_request_.get()); |
| 122 offliner_->Cancel(); | 139 offliner_->Cancel(); |
| 123 // Find current request and mark attempt aborted. | 140 AbortRequestAttempt(active_request_.get()); |
| 124 active_request_->MarkAttemptAborted(); | |
| 125 queue_->UpdateRequest(*(active_request_.get()), | |
| 126 base::Bind(&RequestCoordinator::UpdateRequestCallback, | |
| 127 weak_ptr_factory_.GetWeakPtr(), | |
| 128 active_request_->client_id())); | |
| 129 } | 141 } |
| 130 | 142 |
| 131 // Stopping offliner means it will not call callback. | 143 // Stopping offliner means it will not call callback. |
| 132 last_offlining_status_ = | 144 last_offlining_status_ = |
| 133 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED; | 145 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED; |
| 134 | 146 |
| 135 if (active_request_) { | 147 if (active_request_) { |
| 136 RecordOfflinerResultUMA(active_request_->client_id(), | 148 RecordOfflinerResultUMA(active_request_->client_id(), |
| 137 last_offlining_status_); | 149 last_offlining_status_); |
| 138 is_busy_ = false; | 150 is_busy_ = false; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 150 if (request_ids.end() != std::find(request_ids.begin(), request_ids.end(), | 162 if (request_ids.end() != std::find(request_ids.begin(), request_ids.end(), |
| 151 active_request_->request_id())) { | 163 active_request_->request_id())) { |
| 152 StopPrerendering(); | 164 StopPrerendering(); |
| 153 return true; | 165 return true; |
| 154 } | 166 } |
| 155 } | 167 } |
| 156 | 168 |
| 157 return false; | 169 return false; |
| 158 } | 170 } |
| 159 | 171 |
| 172 void RequestCoordinator::AbortRequestAttempt(SavePageRequest* request) { |
| 173 request->MarkAttemptAborted(); |
| 174 if (request->started_attempt_count() >= policy_->GetMaxStartedTries()) { |
| 175 RemoveAttemptedRequest(*request, SavePageStatus::START_COUNT_EXCEEDED); |
| 176 } else { |
| 177 queue_->UpdateRequest( |
| 178 *request, |
| 179 base::Bind(&RequestCoordinator::UpdateRequestCallback, |
| 180 weak_ptr_factory_.GetWeakPtr(), request->client_id())); |
| 181 } |
| 182 } |
| 183 |
| 184 void RequestCoordinator::RemoveAttemptedRequest(const SavePageRequest& request, |
| 185 SavePageStatus status) { |
| 186 std::vector<int64_t> remove_requests; |
| 187 remove_requests.push_back(request.request_id()); |
| 188 queue_->RemoveRequests(remove_requests, |
| 189 base::Bind(&RequestCoordinator::HandleRemovedRequests, |
| 190 weak_ptr_factory_.GetWeakPtr(), status)); |
| 191 RecordAttemptCount(request, status); |
| 192 } |
| 193 |
| 160 void RequestCoordinator::RemoveRequests( | 194 void RequestCoordinator::RemoveRequests( |
| 161 const std::vector<int64_t>& request_ids, | 195 const std::vector<int64_t>& request_ids, |
| 162 const RemoveRequestsCallback& callback) { | 196 const RemoveRequestsCallback& callback) { |
| 163 bool canceled = CancelActiveRequestIfItMatches(request_ids); | 197 bool canceled = CancelActiveRequestIfItMatches(request_ids); |
| 164 queue_->RemoveRequests( | 198 queue_->RemoveRequests( |
| 165 request_ids, | 199 request_ids, |
| 166 base::Bind(&RequestCoordinator::HandleRemovedRequestsAndCallback, | 200 base::Bind(&RequestCoordinator::HandleRemovedRequestsAndCallback, |
| 167 weak_ptr_factory_.GetWeakPtr(), callback, | 201 weak_ptr_factory_.GetWeakPtr(), callback, |
| 168 SavePageStatus::REMOVED)); | 202 SavePageStatus::REMOVED)); |
| 169 if (canceled) | 203 if (canceled) |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 | 439 |
| 406 is_busy_ = false; | 440 is_busy_ = false; |
| 407 active_request_.reset(nullptr); | 441 active_request_.reset(nullptr); |
| 408 | 442 |
| 409 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED || | 443 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED || |
| 410 status == Offliner::RequestStatus::PRERENDERING_CANCELED) { | 444 status == Offliner::RequestStatus::PRERENDERING_CANCELED) { |
| 411 // Update the request for the canceled attempt. | 445 // Update the request for the canceled attempt. |
| 412 // TODO(dougarnett): See if we can conclusively identify other attempt | 446 // TODO(dougarnett): See if we can conclusively identify other attempt |
| 413 // aborted cases to treat this way (eg, for Render Process Killed). | 447 // aborted cases to treat this way (eg, for Render Process Killed). |
| 414 SavePageRequest updated_request(request); | 448 SavePageRequest updated_request(request); |
| 415 updated_request.MarkAttemptAborted(); | 449 AbortRequestAttempt(&updated_request); |
| 416 queue_->UpdateRequest(updated_request, | |
| 417 base::Bind(&RequestCoordinator::UpdateRequestCallback, | |
| 418 weak_ptr_factory_.GetWeakPtr(), | |
| 419 updated_request.client_id())); | |
| 420 SavePageStatus notify_status = | 450 SavePageStatus notify_status = |
| 421 (status == Offliner::RequestStatus::FOREGROUND_CANCELED) | 451 (status == Offliner::RequestStatus::FOREGROUND_CANCELED) |
| 422 ? SavePageStatus::FOREGROUND_CANCELED | 452 ? SavePageStatus::FOREGROUND_CANCELED |
| 423 : SavePageStatus::PRERENDER_CANCELED; | 453 : SavePageStatus::PRERENDER_CANCELED; |
| 424 NotifyCompleted(updated_request, notify_status); | 454 NotifyCompleted(updated_request, notify_status); |
| 425 | |
| 426 } else if (status == Offliner::RequestStatus::SAVED) { | 455 } else if (status == Offliner::RequestStatus::SAVED) { |
| 427 // Remove the request from the queue if it succeeded. | 456 // Remove the request from the queue if it succeeded. |
| 428 std::vector<int64_t> remove_requests; | 457 RemoveAttemptedRequest(request, SavePageStatus::SUCCESS); |
| 429 remove_requests.push_back(request.request_id()); | |
| 430 queue_->RemoveRequests( | |
| 431 remove_requests, | |
| 432 base::Bind(&RequestCoordinator::HandleRemovedRequests, | |
| 433 weak_ptr_factory_.GetWeakPtr(), SavePageStatus::SUCCESS)); | |
| 434 } else if (request.completed_attempt_count() + 1 >= | 458 } else if (request.completed_attempt_count() + 1 >= |
| 435 policy_->GetMaxCompletedTries()) { | 459 policy_->GetMaxCompletedTries()) { |
| 436 // Remove from the request queue if we exceeeded max retries. The +1 | 460 // Remove from the request queue if we exceeded max retries. The +1 |
| 437 // represents the request that just completed. Since we call | 461 // represents the request that just completed. Since we call |
| 438 // MarkAttemptCompleted within the if branches, the completed_attempt_count | 462 // MarkAttemptCompleted within the if branches, the completed_attempt_count |
| 439 // has not yet been updated when we are checking the if condition. | 463 // has not yet been updated when we are checking the if condition. |
| 440 std::vector<int64_t> remove_requests; | 464 RemoveAttemptedRequest(request, SavePageStatus::RETRY_COUNT_EXCEEDED); |
| 441 remove_requests.push_back(request.request_id()); | |
| 442 queue_->RemoveRequests( | |
| 443 remove_requests, base::Bind(&RequestCoordinator::HandleRemovedRequests, | |
| 444 weak_ptr_factory_.GetWeakPtr(), | |
| 445 SavePageStatus::RETRY_COUNT_EXCEEDED)); | |
| 446 } else { | 465 } else { |
| 447 // If we failed, but are not over the limit, update the request in the | 466 // If we failed, but are not over the limit, update the request in the |
| 448 // queue. | 467 // queue. |
| 449 SavePageRequest updated_request(request); | 468 SavePageRequest updated_request(request); |
| 450 updated_request.MarkAttemptCompleted(); | 469 updated_request.MarkAttemptCompleted(); |
| 451 queue_->UpdateRequest(updated_request, | 470 queue_->UpdateRequest(updated_request, |
| 452 base::Bind(&RequestCoordinator::UpdateRequestCallback, | 471 base::Bind(&RequestCoordinator::UpdateRequestCallback, |
| 453 weak_ptr_factory_.GetWeakPtr(), | 472 weak_ptr_factory_.GetWeakPtr(), |
| 454 updated_request.client_id())); | 473 updated_request.client_id())); |
| 455 NotifyChanged(updated_request); | 474 NotifyChanged(updated_request); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 FOR_EACH_OBSERVER(Observer, observers_, OnChanged(request)); | 529 FOR_EACH_OBSERVER(Observer, observers_, OnChanged(request)); |
| 511 } | 530 } |
| 512 | 531 |
| 513 void RequestCoordinator::GetOffliner() { | 532 void RequestCoordinator::GetOffliner() { |
| 514 if (!offliner_) { | 533 if (!offliner_) { |
| 515 offliner_ = factory_->GetOffliner(policy_.get()); | 534 offliner_ = factory_->GetOffliner(policy_.get()); |
| 516 } | 535 } |
| 517 } | 536 } |
| 518 | 537 |
| 519 } // namespace offline_pages | 538 } // namespace offline_pages |
| OLD | NEW |