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

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

Issue 2209813002: [Offline Pages] Moves Coordinator to using MarkAttemptStarted/MarkAttemptCompleted API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix trybot complaint for no return value on string mapping methods Created 4 years, 4 months 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 <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"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/metrics/histogram_macros.h" 12 #include "base/metrics/histogram_macros.h"
13 #include "base/time/time.h" 13 #include "base/time/time.h"
14 #include "components/offline_pages/background/offliner_factory.h" 14 #include "components/offline_pages/background/offliner_factory.h"
15 #include "components/offline_pages/background/offliner_policy.h" 15 #include "components/offline_pages/background/offliner_policy.h"
16 #include "components/offline_pages/background/request_picker.h" 16 #include "components/offline_pages/background/request_picker.h"
17 #include "components/offline_pages/background/save_page_request.h" 17 #include "components/offline_pages/background/save_page_request.h"
18 #include "components/offline_pages/offline_page_item.h" 18 #include "components/offline_pages/offline_page_item.h"
19 #include "components/offline_pages/offline_page_model.h"
19 20
20 namespace offline_pages { 21 namespace offline_pages {
21 22
22 namespace { 23 namespace {
23 24
24 // Records the final request status UMA for an offlining request. This should 25 // Records the final request status UMA for an offlining request. This should
25 // only be called once per Offliner::LoadAndSave request. 26 // only be called once per Offliner::LoadAndSave request.
26 void RecordOfflinerResultUMA(Offliner::RequestStatus request_status) { 27 void RecordOfflinerResultUMA(Offliner::RequestStatus request_status) {
27 UMA_HISTOGRAM_ENUMERATION("OfflinePages.Background.OfflinerRequestStatus", 28 UMA_HISTOGRAM_ENUMERATION("OfflinePages.Background.OfflinerRequestStatus",
28 request_status, 29 request_status,
(...skipping 20 matching lines...) Expand all
49 DCHECK(policy_ != nullptr); 50 DCHECK(policy_ != nullptr);
50 picker_.reset(new RequestPicker(queue_.get(), policy_.get())); 51 picker_.reset(new RequestPicker(queue_.get(), policy_.get()));
51 } 52 }
52 53
53 RequestCoordinator::~RequestCoordinator() {} 54 RequestCoordinator::~RequestCoordinator() {}
54 55
55 bool RequestCoordinator::SavePageLater( 56 bool RequestCoordinator::SavePageLater(
56 const GURL& url, const ClientId& client_id, bool was_user_requested) { 57 const GURL& url, const ClientId& client_id, bool was_user_requested) {
57 DVLOG(2) << "URL is " << url << " " << __func__; 58 DVLOG(2) << "URL is " << url << " " << __func__;
58 59
60 if (!OfflinePageModel::CanSaveURL(url)) {
61 DVLOG(1) << "Not able to save page for requested url: " << url;
62 return false;
63 }
64
59 // TODO(petewil): We need a robust scheme for allocating new IDs. 65 // TODO(petewil): We need a robust scheme for allocating new IDs.
60 static int64_t id = 0; 66 static int64_t id = 0;
61 67
62 // Build a SavePageRequest. 68 // Build a SavePageRequest.
63 offline_pages::SavePageRequest request( 69 offline_pages::SavePageRequest request(
64 id++, url, client_id, base::Time::Now(), was_user_requested); 70 id++, url, client_id, base::Time::Now(), was_user_requested);
65 71
66 // Put the request on the request queue. 72 // Put the request on the request queue.
67 queue_->AddRequest(request, 73 queue_->AddRequest(request,
68 base::Bind(&RequestCoordinator::AddRequestResultCallback, 74 base::Bind(&RequestCoordinator::AddRequestResultCallback,
69 weak_ptr_factory_.GetWeakPtr())); 75 weak_ptr_factory_.GetWeakPtr()));
70 return true; 76 return true;
71 } 77 }
72 78
73 void RequestCoordinator::RemoveRequests( 79 void RequestCoordinator::RemoveRequests(
74 const std::vector<ClientId>& client_ids) { 80 const std::vector<ClientId>& client_ids) {
75 queue_->RemoveRequestsByClientId( 81 queue_->RemoveRequestsByClientId(
76 client_ids, base::Bind(&RequestCoordinator::UpdateRequestCallback, 82 client_ids, base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback,
77 weak_ptr_factory_.GetWeakPtr())); 83 weak_ptr_factory_.GetWeakPtr()));
78 } 84 }
79 85
80 void RequestCoordinator::AddRequestResultCallback( 86 void RequestCoordinator::AddRequestResultCallback(
81 RequestQueue::AddRequestResult result, 87 RequestQueue::AddRequestResult result,
82 const SavePageRequest& request) { 88 const SavePageRequest& request) {
83 89
84 // Inform the scheduler that we have an outstanding task.. 90 // Inform the scheduler that we have an outstanding task..
85 scheduler_->Schedule(GetTriggerConditionsForUserRequest()); 91 scheduler_->Schedule(GetTriggerConditionsForUserRequest());
86 } 92 }
87 93
88 // Called in response to updating a request in the request queue. 94 // Called in response to updating a request in the request queue.
89 void RequestCoordinator::UpdateRequestCallback( 95 void RequestCoordinator::UpdateRequestCallback(
96 const ClientId& client_id, RequestQueue::UpdateRequestResult result) {
fgorski 2016/08/04 06:01:34 please run git cl format.
dougarnett 2016/08/04 16:24:38 Done.
97 // If the request succeeded, nothing to do. If it failed, we can't really do
98 // much, so just log it.
99 if (result != RequestQueue::UpdateRequestResult::SUCCESS) {
100 DLOG(WARNING) << "Failed to update request attempt details. "
fgorski 2016/08/04 06:01:34 nit: use DVLOG here too
dougarnett 2016/08/04 16:24:38 Done.
101 << static_cast<int>(result);
102 event_logger_.RecordUpdateRequestFailed(
103 client_id.name_space,
104 RequestQueue::UpdateRequestResultToString(result));
105 }
106 }
107
108 // Called in response to updating multiple requests in the request queue.
109 void RequestCoordinator::UpdateMultipleRequestCallback(
90 RequestQueue::UpdateRequestResult result) { 110 RequestQueue::UpdateRequestResult result) {
91 // If the request succeeded, nothing to do. If it failed, we can't really do 111 // If the request succeeded, nothing to do. If it failed, we can't really do
92 // much, so just log it. 112 // much, so just log it.
93 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { 113 if (result != RequestQueue::UpdateRequestResult::SUCCESS) {
94 // TODO(petewil): Consider adding UMA or showing on offline-internals page. 114 DLOG(WARNING) << "Failed to update request attempt details. "
95 DLOG(WARNING) << "Failed to update a request retry count. "
96 << static_cast<int>(result); 115 << static_cast<int>(result);
97 } 116 }
98 } 117 }
99 118
100 void RequestCoordinator::StopProcessing() { 119 void RequestCoordinator::StopProcessing() {
101 is_canceled_ = true; 120 is_canceled_ = true;
102 if (offliner_ && is_busy_) 121 if (offliner_ && is_busy_) {
122 // TODO(dougarnett): Find current request and mark attempt aborted.
103 offliner_->Cancel(); 123 offliner_->Cancel();
124 }
104 125
105 // Stopping offliner means it will not call callback. 126 // Stopping offliner means it will not call callback.
106 last_offlining_status_ = 127 last_offlining_status_ =
107 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED; 128 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED;
108 RecordOfflinerResultUMA(last_offlining_status_); 129 RecordOfflinerResultUMA(last_offlining_status_);
109 130
110 // Let the scheduler know we are done processing. 131 // Let the scheduler know we are done processing.
111 scheduler_callback_.Run(true); 132 scheduler_callback_.Run(true);
112 } 133 }
113 134
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 GetOffliner(); 198 GetOffliner();
178 if (!offliner_) { 199 if (!offliner_) {
179 DVLOG(0) << "Unable to create Offliner. " 200 DVLOG(0) << "Unable to create Offliner. "
180 << "Cannot background offline page."; 201 << "Cannot background offline page.";
181 return; 202 return;
182 } 203 }
183 204
184 DCHECK(!is_busy_); 205 DCHECK(!is_busy_);
185 is_busy_ = true; 206 is_busy_ = true;
186 207
208 // Prepare an updated request to attempt.
209 SavePageRequest updated_request(request);
210 updated_request.MarkAttemptStarted(base::Time::Now());
211
187 // Start the load and save process in the offliner (Async). 212 // Start the load and save process in the offliner (Async).
188 offliner_->LoadAndSave(request, 213 if (offliner_->LoadAndSave(updated_request,
189 base::Bind(&RequestCoordinator::OfflinerDoneCallback, 214 base::Bind(&RequestCoordinator::OfflinerDoneCallback,
fgorski 2016/08/04 06:01:34 nit: alignment
dougarnett 2016/08/04 16:24:38 Done.
190 weak_ptr_factory_.GetWeakPtr())); 215 weak_ptr_factory_.GetWeakPtr()))) {
216 // Offliner accepted request so update it in the queue.
217 queue_->UpdateRequest(
218 updated_request,
219 base::Bind(&RequestCoordinator::UpdateRequestCallback,
220 weak_ptr_factory_.GetWeakPtr(),
221 updated_request.client_id()));
191 222
192 // Start a watchdog timer to catch pre-renders running too long 223 // Start a watchdog timer to catch pre-renders running too long
193 watchdog_timer_.Start(FROM_HERE, offliner_timeout_, this, 224 watchdog_timer_.Start(FROM_HERE, offliner_timeout_, this,
194 &RequestCoordinator::StopProcessing); 225 &RequestCoordinator::StopProcessing);
226 } else {
227 is_busy_ = false;
228 DVLOG(0) << "Unable to start LoadAndSave";
229 StopProcessing();
230 }
195 } 231 }
196 232
197 void RequestCoordinator::OfflinerDoneCallback(const SavePageRequest& request, 233 void RequestCoordinator::OfflinerDoneCallback(const SavePageRequest& request,
198 Offliner::RequestStatus status) { 234 Offliner::RequestStatus status) {
199 DVLOG(2) << "offliner finished, saved: " 235 DVLOG(2) << "offliner finished, saved: "
200 << (status == Offliner::RequestStatus::SAVED) 236 << (status == Offliner::RequestStatus::SAVED)
201 << ", status: " << static_cast<int>(status) << ", " << __func__; 237 << ", status: " << static_cast<int>(status) << ", " << __func__;
202 DCHECK_NE(status, Offliner::RequestStatus::UNKNOWN); 238 DCHECK_NE(status, Offliner::RequestStatus::UNKNOWN);
203 DCHECK_NE(status, Offliner::RequestStatus::LOADED); 239 DCHECK_NE(status, Offliner::RequestStatus::LOADED);
204 event_logger_.RecordSavePageRequestUpdated( 240 event_logger_.RecordSavePageRequestUpdated(
205 request.client_id().name_space, 241 request.client_id().name_space,
206 "Saved", 242 Offliner::RequestStatusToString(status),
207 request.request_id()); 243 request.request_id());
208 last_offlining_status_ = status; 244 last_offlining_status_ = status;
209 RecordOfflinerResultUMA(last_offlining_status_); 245 RecordOfflinerResultUMA(last_offlining_status_);
210 watchdog_timer_.Stop(); 246 watchdog_timer_.Stop();
211 247
212 is_busy_ = false; 248 is_busy_ = false;
213 249
214 int64_t new_attempt_count = request.attempt_count() + 1; 250 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) {
251 // Update the request for the canceled attempt.
252 // TODO(dougarnett): See if we can conclusively identify other attempt
253 // aborted cases to treat this way (eg, for Render Process Killed).
254 SavePageRequest updated_request(request);
255 updated_request.MarkAttemptAborted();
256 queue_->UpdateRequest(
257 updated_request,
258 base::Bind(&RequestCoordinator::UpdateRequestCallback,
259 weak_ptr_factory_.GetWeakPtr(),
260 updated_request.client_id()));
215 261
216 // Remove the request from the queue if it either succeeded or exceeded the 262 } else if (status == Offliner::RequestStatus::SAVED
217 // max number of retries. 263 || request.attempt_count() >= policy_->GetMaxTries()) {
218 if (status == Offliner::RequestStatus::SAVED 264 // Remove the request from the queue if it either succeeded or exceeded the
219 || new_attempt_count > policy_->GetMaxTries()) { 265 // max number of retries.
220 queue_->RemoveRequest(request.request_id(), 266 queue_->RemoveRequest(request.request_id(),
221 base::Bind(&RequestCoordinator::UpdateRequestCallback, 267 base::Bind(&RequestCoordinator::UpdateRequestCallback,
222 weak_ptr_factory_.GetWeakPtr())); 268 weak_ptr_factory_.GetWeakPtr(),
269 request.client_id()));
223 } else { 270 } else {
224 // If we failed, but are not over the limit, update the request in the 271 // If we failed, but are not over the limit, update the request in the
225 // queue. 272 // queue.
226 SavePageRequest updated_request(request); 273 SavePageRequest updated_request(request);
227 updated_request.set_attempt_count(new_attempt_count); 274 updated_request.MarkAttemptCompleted();
228 updated_request.set_last_attempt_time(base::Time::Now());
229 RequestQueue::UpdateRequestCallback update_callback =
230 base::Bind(&RequestCoordinator::UpdateRequestCallback,
231 weak_ptr_factory_.GetWeakPtr());
232 queue_->UpdateRequest( 275 queue_->UpdateRequest(
233 updated_request, 276 updated_request,
234 base::Bind(&RequestCoordinator::UpdateRequestCallback, 277 base::Bind(&RequestCoordinator::UpdateRequestCallback,
235 weak_ptr_factory_.GetWeakPtr())); 278 weak_ptr_factory_.GetWeakPtr(),
279 updated_request.client_id()));
236 } 280 }
237 281
238 // Determine whether we might try another request in this 282 // Determine whether we might try another request in this
239 // processing window based on how the previous request completed. 283 // processing window based on how the previous request completed.
240 // 284 //
241 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate 285 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate
242 // codes as to whether we should try another request or not. 286 // codes as to whether we should try another request or not.
243 switch (status) { 287 switch (status) {
244 case Offliner::RequestStatus::SAVED: 288 case Offliner::RequestStatus::SAVED:
245 case Offliner::RequestStatus::SAVE_FAILED: 289 case Offliner::RequestStatus::SAVE_FAILED:
(...skipping 22 matching lines...) Expand all
268 return trigger_conditions; 312 return trigger_conditions;
269 } 313 }
270 314
271 void RequestCoordinator::GetOffliner() { 315 void RequestCoordinator::GetOffliner() {
272 if (!offliner_) { 316 if (!offliner_) {
273 offliner_ = factory_->GetOffliner(policy_.get()); 317 offliner_ = factory_->GetOffliner(policy_.get());
274 } 318 }
275 } 319 }
276 320
277 } // namespace offline_pages 321 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698