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

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: Move enum2string functions to event logger and addressed some other Filip feedback 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,
29 Offliner::RequestStatus::STATUS_COUNT); 30 Offliner::RequestStatus::STATUS_COUNT);
30 } 31 }
31 32
32 } // namespace 33 } // namespaceconst std::string&
fgorski 2016/08/04 16:51:50 fix the accidental paste, please.
dougarnett 2016/08/04 16:57:20 ug, thanks!
33 34
34 RequestCoordinator::RequestCoordinator(std::unique_ptr<OfflinerPolicy> policy, 35 RequestCoordinator::RequestCoordinator(std::unique_ptr<OfflinerPolicy> policy,
35 std::unique_ptr<OfflinerFactory> factory, 36 std::unique_ptr<OfflinerFactory> factory,
36 std::unique_ptr<RequestQueue> queue, 37 std::unique_ptr<RequestQueue> queue,
37 std::unique_ptr<Scheduler> scheduler) 38 std::unique_ptr<Scheduler> scheduler)
38 : is_busy_(false), 39 : is_busy_(false),
39 is_canceled_(false), 40 is_canceled_(false),
40 offliner_(nullptr), 41 offliner_(nullptr),
41 policy_(std::move(policy)), 42 policy_(std::move(policy)),
42 factory_(std::move(factory)), 43 factory_(std::move(factory)),
43 queue_(std::move(queue)), 44 queue_(std::move(queue)),
44 scheduler_(std::move(scheduler)), 45 scheduler_(std::move(scheduler)),
45 last_offlining_status_(Offliner::RequestStatus::UNKNOWN), 46 last_offlining_status_(Offliner::RequestStatus::UNKNOWN),
46 offliner_timeout_(base::TimeDelta::FromSeconds( 47 offliner_timeout_(base::TimeDelta::FromSeconds(
47 policy_->GetSinglePageTimeLimitInSeconds())), 48 policy_->GetSinglePageTimeLimitInSeconds())),
48 weak_ptr_factory_(this) { 49 weak_ptr_factory_(this) {
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,
90 RequestQueue::UpdateRequestResult result) { 97 RequestQueue::UpdateRequestResult result) {
91 // If the request succeeded, nothing to do. If it failed, we can't really do 98 // If the request succeeded, nothing to do. If it failed, we can't really do
92 // much, so just log it. 99 // much, so just log it.
93 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { 100 if (result != RequestQueue::UpdateRequestResult::SUCCESS) {
94 // TODO(petewil): Consider adding UMA or showing on offline-internals page. 101 DVLOG(1) << "Failed to update request attempt details. "
95 DLOG(WARNING) << "Failed to update a request retry count. " 102 << static_cast<int>(result);
96 << static_cast<int>(result); 103 event_logger_.RecordUpdateRequestFailed(client_id.name_space, result);
104 }
105 }
106
107 // Called in response to updating multiple requests in the request queue.
108 void RequestCoordinator::UpdateMultipleRequestCallback(
109 RequestQueue::UpdateRequestResult result) {
110 // If the request succeeded, nothing to do. If it failed, we can't really do
111 // much, so just log it.
112 if (result != RequestQueue::UpdateRequestResult::SUCCESS) {
113 DVLOG(1) << "Failed to update request attempt details. "
114 << static_cast<int>(result);
97 } 115 }
98 } 116 }
99 117
100 void RequestCoordinator::StopProcessing() { 118 void RequestCoordinator::StopProcessing() {
101 is_canceled_ = true; 119 is_canceled_ = true;
102 if (offliner_ && is_busy_) 120 if (offliner_ && is_busy_) {
121 // TODO(dougarnett): Find current request and mark attempt aborted.
103 offliner_->Cancel(); 122 offliner_->Cancel();
123 }
104 124
105 // Stopping offliner means it will not call callback. 125 // Stopping offliner means it will not call callback.
106 last_offlining_status_ = 126 last_offlining_status_ =
107 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED; 127 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED;
108 RecordOfflinerResultUMA(last_offlining_status_); 128 RecordOfflinerResultUMA(last_offlining_status_);
109 129
110 // Let the scheduler know we are done processing. 130 // Let the scheduler know we are done processing.
111 scheduler_callback_.Run(true); 131 scheduler_callback_.Run(true);
112 } 132 }
113 133
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 GetOffliner(); 197 GetOffliner();
178 if (!offliner_) { 198 if (!offliner_) {
179 DVLOG(0) << "Unable to create Offliner. " 199 DVLOG(0) << "Unable to create Offliner. "
180 << "Cannot background offline page."; 200 << "Cannot background offline page.";
181 return; 201 return;
182 } 202 }
183 203
184 DCHECK(!is_busy_); 204 DCHECK(!is_busy_);
185 is_busy_ = true; 205 is_busy_ = true;
186 206
207 // Prepare an updated request to attempt.
208 SavePageRequest updated_request(request);
209 updated_request.MarkAttemptStarted(base::Time::Now());
210
187 // Start the load and save process in the offliner (Async). 211 // Start the load and save process in the offliner (Async).
188 offliner_->LoadAndSave(request, 212 if (offliner_->LoadAndSave(
189 base::Bind(&RequestCoordinator::OfflinerDoneCallback, 213 updated_request, base::Bind(&RequestCoordinator::OfflinerDoneCallback,
190 weak_ptr_factory_.GetWeakPtr())); 214 weak_ptr_factory_.GetWeakPtr()))) {
215 // Offliner accepted request so update it in the queue.
216 queue_->UpdateRequest(updated_request,
217 base::Bind(&RequestCoordinator::UpdateRequestCallback,
218 weak_ptr_factory_.GetWeakPtr(),
219 updated_request.client_id()));
191 220
192 // Start a watchdog timer to catch pre-renders running too long 221 // Start a watchdog timer to catch pre-renders running too long
193 watchdog_timer_.Start(FROM_HERE, offliner_timeout_, this, 222 watchdog_timer_.Start(FROM_HERE, offliner_timeout_, this,
194 &RequestCoordinator::StopProcessing); 223 &RequestCoordinator::StopProcessing);
224 } else {
225 is_busy_ = false;
226 DVLOG(0) << "Unable to start LoadAndSave";
227 StopProcessing();
228 }
195 } 229 }
196 230
197 void RequestCoordinator::OfflinerDoneCallback(const SavePageRequest& request, 231 void RequestCoordinator::OfflinerDoneCallback(const SavePageRequest& request,
198 Offliner::RequestStatus status) { 232 Offliner::RequestStatus status) {
199 DVLOG(2) << "offliner finished, saved: " 233 DVLOG(2) << "offliner finished, saved: "
200 << (status == Offliner::RequestStatus::SAVED) 234 << (status == Offliner::RequestStatus::SAVED)
201 << ", status: " << static_cast<int>(status) << ", " << __func__; 235 << ", status: " << static_cast<int>(status) << ", " << __func__;
202 DCHECK_NE(status, Offliner::RequestStatus::UNKNOWN); 236 DCHECK_NE(status, Offliner::RequestStatus::UNKNOWN);
203 DCHECK_NE(status, Offliner::RequestStatus::LOADED); 237 DCHECK_NE(status, Offliner::RequestStatus::LOADED);
204 event_logger_.RecordSavePageRequestUpdated( 238 event_logger_.RecordSavePageRequestUpdated(request.client_id().name_space,
205 request.client_id().name_space, 239 status, request.request_id());
206 "Saved",
207 request.request_id());
208 last_offlining_status_ = status; 240 last_offlining_status_ = status;
209 RecordOfflinerResultUMA(last_offlining_status_); 241 RecordOfflinerResultUMA(last_offlining_status_);
210 watchdog_timer_.Stop(); 242 watchdog_timer_.Stop();
211 243
212 is_busy_ = false; 244 is_busy_ = false;
213 245
214 int64_t new_attempt_count = request.attempt_count() + 1; 246 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) {
247 // Update the request for the canceled attempt.
248 // TODO(dougarnett): See if we can conclusively identify other attempt
249 // aborted cases to treat this way (eg, for Render Process Killed).
250 SavePageRequest updated_request(request);
251 updated_request.MarkAttemptAborted();
252 queue_->UpdateRequest(updated_request,
253 base::Bind(&RequestCoordinator::UpdateRequestCallback,
254 weak_ptr_factory_.GetWeakPtr(),
255 updated_request.client_id()));
215 256
216 // Remove the request from the queue if it either succeeded or exceeded the 257 } else if (status == Offliner::RequestStatus::SAVED ||
217 // max number of retries. 258 request.attempt_count() >= policy_->GetMaxTries()) {
218 if (status == Offliner::RequestStatus::SAVED 259 // Remove the request from the queue if it either succeeded or exceeded the
219 || new_attempt_count > policy_->GetMaxTries()) { 260 // max number of retries.
220 queue_->RemoveRequest(request.request_id(), 261 queue_->RemoveRequest(
221 base::Bind(&RequestCoordinator::UpdateRequestCallback, 262 request.request_id(),
222 weak_ptr_factory_.GetWeakPtr())); 263 base::Bind(&RequestCoordinator::UpdateRequestCallback,
264 weak_ptr_factory_.GetWeakPtr(), request.client_id()));
223 } else { 265 } else {
224 // If we failed, but are not over the limit, update the request in the 266 // If we failed, but are not over the limit, update the request in the
225 // queue. 267 // queue.
226 SavePageRequest updated_request(request); 268 SavePageRequest updated_request(request);
227 updated_request.set_attempt_count(new_attempt_count); 269 updated_request.MarkAttemptCompleted();
228 updated_request.set_last_attempt_time(base::Time::Now()); 270 queue_->UpdateRequest(updated_request,
229 RequestQueue::UpdateRequestCallback update_callback = 271 base::Bind(&RequestCoordinator::UpdateRequestCallback,
230 base::Bind(&RequestCoordinator::UpdateRequestCallback, 272 weak_ptr_factory_.GetWeakPtr(),
231 weak_ptr_factory_.GetWeakPtr()); 273 updated_request.client_id()));
232 queue_->UpdateRequest(
233 updated_request,
234 base::Bind(&RequestCoordinator::UpdateRequestCallback,
235 weak_ptr_factory_.GetWeakPtr()));
236 } 274 }
237 275
238 // Determine whether we might try another request in this 276 // Determine whether we might try another request in this
239 // processing window based on how the previous request completed. 277 // processing window based on how the previous request completed.
240 // 278 //
241 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate 279 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate
242 // codes as to whether we should try another request or not. 280 // codes as to whether we should try another request or not.
243 switch (status) { 281 switch (status) {
244 case Offliner::RequestStatus::SAVED: 282 case Offliner::RequestStatus::SAVED:
245 case Offliner::RequestStatus::SAVE_FAILED: 283 case Offliner::RequestStatus::SAVE_FAILED:
(...skipping 22 matching lines...) Expand all
268 return trigger_conditions; 306 return trigger_conditions;
269 } 307 }
270 308
271 void RequestCoordinator::GetOffliner() { 309 void RequestCoordinator::GetOffliner() {
272 if (!offliner_) { 310 if (!offliner_) {
273 offliner_ = factory_->GetOffliner(policy_.get()); 311 offliner_ = factory_->GetOffliner(policy_.get());
274 } 312 }
275 } 313 }
276 314
277 } // namespace offline_pages 315 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698