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

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: Merge 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,
(...skipping 23 matching lines...) Expand all
92 if (client_namespace == request.client_id().name_space) 98 if (client_namespace == request.client_id().name_space)
93 client_ids.push_back(request.client_id()); 99 client_ids.push_back(request.client_id());
94 } 100 }
95 101
96 callback.Run(client_ids); 102 callback.Run(client_ids);
97 } 103 }
98 104
99 void RequestCoordinator::RemoveRequests( 105 void RequestCoordinator::RemoveRequests(
100 const std::vector<ClientId>& client_ids) { 106 const std::vector<ClientId>& client_ids) {
101 queue_->RemoveRequestsByClientId( 107 queue_->RemoveRequestsByClientId(
102 client_ids, base::Bind(&RequestCoordinator::UpdateRequestCallback, 108 client_ids, base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback,
103 weak_ptr_factory_.GetWeakPtr())); 109 weak_ptr_factory_.GetWeakPtr()));
104 } 110 }
105 111
106 void RequestCoordinator::AddRequestResultCallback( 112 void RequestCoordinator::AddRequestResultCallback(
107 RequestQueue::AddRequestResult result, 113 RequestQueue::AddRequestResult result,
108 const SavePageRequest& request) { 114 const SavePageRequest& request) {
109 115
110 // Inform the scheduler that we have an outstanding task.. 116 // Inform the scheduler that we have an outstanding task..
111 scheduler_->Schedule(GetTriggerConditionsForUserRequest()); 117 scheduler_->Schedule(GetTriggerConditionsForUserRequest());
112 } 118 }
113 119
114 // Called in response to updating a request in the request queue. 120 // Called in response to updating a request in the request queue.
115 void RequestCoordinator::UpdateRequestCallback( 121 void RequestCoordinator::UpdateRequestCallback(
122 const ClientId& client_id,
116 RequestQueue::UpdateRequestResult result) { 123 RequestQueue::UpdateRequestResult result) {
117 // If the request succeeded, nothing to do. If it failed, we can't really do 124 // If the request succeeded, nothing to do. If it failed, we can't really do
118 // much, so just log it. 125 // much, so just log it.
119 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { 126 if (result != RequestQueue::UpdateRequestResult::SUCCESS) {
120 // TODO(petewil): Consider adding UMA or showing on offline-internals page. 127 DVLOG(1) << "Failed to update request attempt details. "
121 DLOG(WARNING) << "Failed to update a request retry count. " 128 << static_cast<int>(result);
122 << static_cast<int>(result); 129 event_logger_.RecordUpdateRequestFailed(client_id.name_space, result);
130 }
131 }
132
133 // Called in response to updating multiple requests in the request queue.
134 void RequestCoordinator::UpdateMultipleRequestCallback(
135 RequestQueue::UpdateRequestResult result) {
136 // If the request succeeded, nothing to do. If it failed, we can't really do
137 // much, so just log it.
138 if (result != RequestQueue::UpdateRequestResult::SUCCESS) {
139 DVLOG(1) << "Failed to update request attempt details. "
140 << static_cast<int>(result);
123 } 141 }
124 } 142 }
125 143
126 void RequestCoordinator::StopProcessing() { 144 void RequestCoordinator::StopProcessing() {
127 is_canceled_ = true; 145 is_canceled_ = true;
128 if (offliner_ && is_busy_) 146 if (offliner_ && is_busy_) {
147 // TODO(dougarnett): Find current request and mark attempt aborted.
129 offliner_->Cancel(); 148 offliner_->Cancel();
149 }
130 150
131 // Stopping offliner means it will not call callback. 151 // Stopping offliner means it will not call callback.
132 last_offlining_status_ = 152 last_offlining_status_ =
133 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED; 153 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED;
134 RecordOfflinerResultUMA(last_offlining_status_); 154 RecordOfflinerResultUMA(last_offlining_status_);
135 155
136 // Let the scheduler know we are done processing. 156 // Let the scheduler know we are done processing.
137 scheduler_callback_.Run(true); 157 scheduler_callback_.Run(true);
138 } 158 }
139 159
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 GetOffliner(); 223 GetOffliner();
204 if (!offliner_) { 224 if (!offliner_) {
205 DVLOG(0) << "Unable to create Offliner. " 225 DVLOG(0) << "Unable to create Offliner. "
206 << "Cannot background offline page."; 226 << "Cannot background offline page.";
207 return; 227 return;
208 } 228 }
209 229
210 DCHECK(!is_busy_); 230 DCHECK(!is_busy_);
211 is_busy_ = true; 231 is_busy_ = true;
212 232
233 // Prepare an updated request to attempt.
234 SavePageRequest updated_request(request);
235 updated_request.MarkAttemptStarted(base::Time::Now());
236
213 // Start the load and save process in the offliner (Async). 237 // Start the load and save process in the offliner (Async).
214 offliner_->LoadAndSave(request, 238 if (offliner_->LoadAndSave(
215 base::Bind(&RequestCoordinator::OfflinerDoneCallback, 239 updated_request, base::Bind(&RequestCoordinator::OfflinerDoneCallback,
216 weak_ptr_factory_.GetWeakPtr())); 240 weak_ptr_factory_.GetWeakPtr()))) {
241 // Offliner accepted request so update it in the queue.
242 queue_->UpdateRequest(updated_request,
243 base::Bind(&RequestCoordinator::UpdateRequestCallback,
244 weak_ptr_factory_.GetWeakPtr(),
245 updated_request.client_id()));
217 246
218 // Start a watchdog timer to catch pre-renders running too long 247 // Start a watchdog timer to catch pre-renders running too long
219 watchdog_timer_.Start(FROM_HERE, offliner_timeout_, this, 248 watchdog_timer_.Start(FROM_HERE, offliner_timeout_, this,
220 &RequestCoordinator::StopProcessing); 249 &RequestCoordinator::StopProcessing);
250 } else {
251 is_busy_ = false;
252 DVLOG(0) << "Unable to start LoadAndSave";
253 StopProcessing();
254 }
221 } 255 }
222 256
223 void RequestCoordinator::OfflinerDoneCallback(const SavePageRequest& request, 257 void RequestCoordinator::OfflinerDoneCallback(const SavePageRequest& request,
224 Offliner::RequestStatus status) { 258 Offliner::RequestStatus status) {
225 DVLOG(2) << "offliner finished, saved: " 259 DVLOG(2) << "offliner finished, saved: "
226 << (status == Offliner::RequestStatus::SAVED) 260 << (status == Offliner::RequestStatus::SAVED)
227 << ", status: " << static_cast<int>(status) << ", " << __func__; 261 << ", status: " << static_cast<int>(status) << ", " << __func__;
228 DCHECK_NE(status, Offliner::RequestStatus::UNKNOWN); 262 DCHECK_NE(status, Offliner::RequestStatus::UNKNOWN);
229 DCHECK_NE(status, Offliner::RequestStatus::LOADED); 263 DCHECK_NE(status, Offliner::RequestStatus::LOADED);
230 event_logger_.RecordSavePageRequestUpdated( 264 event_logger_.RecordSavePageRequestUpdated(request.client_id().name_space,
231 request.client_id().name_space, 265 status, request.request_id());
232 "Saved",
233 request.request_id());
234 last_offlining_status_ = status; 266 last_offlining_status_ = status;
235 RecordOfflinerResultUMA(last_offlining_status_); 267 RecordOfflinerResultUMA(last_offlining_status_);
236 watchdog_timer_.Stop(); 268 watchdog_timer_.Stop();
237 269
238 is_busy_ = false; 270 is_busy_ = false;
239 271
240 int64_t new_attempt_count = request.attempt_count() + 1; 272 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) {
273 // Update the request for the canceled attempt.
274 // TODO(dougarnett): See if we can conclusively identify other attempt
275 // aborted cases to treat this way (eg, for Render Process Killed).
276 SavePageRequest updated_request(request);
277 updated_request.MarkAttemptAborted();
278 queue_->UpdateRequest(updated_request,
279 base::Bind(&RequestCoordinator::UpdateRequestCallback,
280 weak_ptr_factory_.GetWeakPtr(),
281 updated_request.client_id()));
241 282
242 // Remove the request from the queue if it either succeeded or exceeded the 283 } else if (status == Offliner::RequestStatus::SAVED ||
243 // max number of retries. 284 request.attempt_count() >= policy_->GetMaxTries()) {
244 if (status == Offliner::RequestStatus::SAVED 285 // Remove the request from the queue if it either succeeded or exceeded the
245 || new_attempt_count > policy_->GetMaxTries()) { 286 // max number of retries.
246 queue_->RemoveRequest(request.request_id(), 287 queue_->RemoveRequest(
247 base::Bind(&RequestCoordinator::UpdateRequestCallback, 288 request.request_id(),
248 weak_ptr_factory_.GetWeakPtr())); 289 base::Bind(&RequestCoordinator::UpdateRequestCallback,
290 weak_ptr_factory_.GetWeakPtr(), request.client_id()));
249 } else { 291 } else {
250 // If we failed, but are not over the limit, update the request in the 292 // If we failed, but are not over the limit, update the request in the
251 // queue. 293 // queue.
252 SavePageRequest updated_request(request); 294 SavePageRequest updated_request(request);
253 updated_request.set_attempt_count(new_attempt_count); 295 updated_request.MarkAttemptCompleted();
254 updated_request.set_last_attempt_time(base::Time::Now()); 296 queue_->UpdateRequest(updated_request,
255 RequestQueue::UpdateRequestCallback update_callback = 297 base::Bind(&RequestCoordinator::UpdateRequestCallback,
256 base::Bind(&RequestCoordinator::UpdateRequestCallback, 298 weak_ptr_factory_.GetWeakPtr(),
257 weak_ptr_factory_.GetWeakPtr()); 299 updated_request.client_id()));
258 queue_->UpdateRequest(
259 updated_request,
260 base::Bind(&RequestCoordinator::UpdateRequestCallback,
261 weak_ptr_factory_.GetWeakPtr()));
262 } 300 }
263 301
264 // Determine whether we might try another request in this 302 // Determine whether we might try another request in this
265 // processing window based on how the previous request completed. 303 // processing window based on how the previous request completed.
266 // 304 //
267 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate 305 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate
268 // codes as to whether we should try another request or not. 306 // codes as to whether we should try another request or not.
269 switch (status) { 307 switch (status) {
270 case Offliner::RequestStatus::SAVED: 308 case Offliner::RequestStatus::SAVED:
271 case Offliner::RequestStatus::SAVE_FAILED: 309 case Offliner::RequestStatus::SAVE_FAILED:
(...skipping 22 matching lines...) Expand all
294 return trigger_conditions; 332 return trigger_conditions;
295 } 333 }
296 334
297 void RequestCoordinator::GetOffliner() { 335 void RequestCoordinator::GetOffliner() {
298 if (!offliner_) { 336 if (!offliner_) {
299 offliner_ = factory_->GetOffliner(policy_.get()); 337 offliner_ = factory_->GetOffliner(policy_.get());
300 } 338 }
301 } 339 }
302 340
303 } // namespace offline_pages 341 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698