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

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

Issue 2266323002: Cancel prerendering when a request is paused or removed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rename flag Created 4 years, 3 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"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1; 51 return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1;
52 } 52 }
53 53
54 } // namespace 54 } // namespace
55 55
56 RequestCoordinator::RequestCoordinator(std::unique_ptr<OfflinerPolicy> policy, 56 RequestCoordinator::RequestCoordinator(std::unique_ptr<OfflinerPolicy> policy,
57 std::unique_ptr<OfflinerFactory> factory, 57 std::unique_ptr<OfflinerFactory> factory,
58 std::unique_ptr<RequestQueue> queue, 58 std::unique_ptr<RequestQueue> queue,
59 std::unique_ptr<Scheduler> scheduler) 59 std::unique_ptr<Scheduler> scheduler)
60 : is_busy_(false), 60 : is_busy_(false),
61 is_canceled_(false), 61 is_stopped_(false),
62 offliner_(nullptr), 62 offliner_(nullptr),
63 policy_(std::move(policy)), 63 policy_(std::move(policy)),
64 factory_(std::move(factory)), 64 factory_(std::move(factory)),
65 queue_(std::move(queue)), 65 queue_(std::move(queue)),
66 scheduler_(std::move(scheduler)), 66 scheduler_(std::move(scheduler)),
67 active_request_(nullptr), 67 active_request_(nullptr),
68 last_offlining_status_(Offliner::RequestStatus::UNKNOWN), 68 last_offlining_status_(Offliner::RequestStatus::UNKNOWN),
69 offliner_timeout_(base::TimeDelta::FromSeconds( 69 offliner_timeout_(base::TimeDelta::FromSeconds(
70 policy_->GetSinglePageTimeLimitInSeconds())), 70 policy_->GetSinglePageTimeLimitInSeconds())),
71 weak_ptr_factory_(this) { 71 weak_ptr_factory_(this) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 weak_ptr_factory_.GetWeakPtr(), callback)); 105 weak_ptr_factory_.GetWeakPtr(), callback));
106 } 106 }
107 107
108 void RequestCoordinator::GetQueuedRequestsCallback( 108 void RequestCoordinator::GetQueuedRequestsCallback(
109 const GetRequestsCallback& callback, 109 const GetRequestsCallback& callback,
110 RequestQueue::GetRequestsResult result, 110 RequestQueue::GetRequestsResult result,
111 const std::vector<SavePageRequest>& requests) { 111 const std::vector<SavePageRequest>& requests) {
112 callback.Run(requests); 112 callback.Run(requests);
113 } 113 }
114 114
115 void RequestCoordinator::StopPrerendering() {
116 if (offliner_ && is_busy_) {
117 offliner_->Cancel();
118 // Find current request and mark attempt aborted.
119 active_request_->MarkAttemptAborted();
120 queue_->UpdateRequest(*(active_request_.get()),
121 base::Bind(&RequestCoordinator::UpdateRequestCallback,
122 weak_ptr_factory_.GetWeakPtr(),
123 active_request_->client_id()));
124 }
125
126 // Stopping offliner means it will not call callback.
127 last_offlining_status_ =
128 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED;
129
130 if (active_request_) {
131 RecordOfflinerResultUMA(active_request_->client_id(),
132 last_offlining_status_);
133 active_request_.reset();
134 }
135
136 }
137
138 bool RequestCoordinator::CancelActiveRequestIfItMatches(
139 const std::vector<int64_t>& request_ids) {
140 // If we have a request in progress and need to cancel it, call the
141 // pre-renderer to cancel. TODO Make sure we remove any page created by the
142 // prerenderer if it doesn't get the cancel in time.
143 if (active_request_ != nullptr) {
144 if (request_ids.end() != std::find(request_ids.begin(), request_ids.end(),
145 active_request_->request_id())) {
146 StopPrerendering();
147 return true;
148 }
149 }
150
151 return false;
152 }
153
115 void RequestCoordinator::RemoveRequests( 154 void RequestCoordinator::RemoveRequests(
116 const std::vector<int64_t>& request_ids) { 155 const std::vector<int64_t>& request_ids) {
156 bool canceled = CancelActiveRequestIfItMatches(request_ids);
117 queue_->RemoveRequests(request_ids, 157 queue_->RemoveRequests(request_ids,
118 base::Bind(&RequestCoordinator::RemoveRequestsCallback, 158 base::Bind(&RequestCoordinator::RemoveRequestsCallback,
119 weak_ptr_factory_.GetWeakPtr())); 159 weak_ptr_factory_.GetWeakPtr()));
160 if (canceled)
161 TryNextRequest();
120 } 162 }
121 163
122 void RequestCoordinator::PauseRequests( 164 void RequestCoordinator::PauseRequests(
123 const std::vector<int64_t>& request_ids) { 165 const std::vector<int64_t>& request_ids) {
166 bool canceled = CancelActiveRequestIfItMatches(request_ids);
124 queue_->ChangeRequestsState( 167 queue_->ChangeRequestsState(
125 request_ids, SavePageRequest::RequestState::PAUSED, 168 request_ids, SavePageRequest::RequestState::PAUSED,
126 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback, 169 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback,
127 weak_ptr_factory_.GetWeakPtr())); 170 weak_ptr_factory_.GetWeakPtr()));
171
172 if (canceled)
173 TryNextRequest();
128 } 174 }
129 175
130 void RequestCoordinator::ResumeRequests( 176 void RequestCoordinator::ResumeRequests(
131 const std::vector<int64_t>& request_ids) { 177 const std::vector<int64_t>& request_ids) {
132 queue_->ChangeRequestsState( 178 queue_->ChangeRequestsState(
133 request_ids, SavePageRequest::RequestState::AVAILABLE, 179 request_ids, SavePageRequest::RequestState::AVAILABLE,
134 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback, 180 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback,
135 weak_ptr_factory_.GetWeakPtr())); 181 weak_ptr_factory_.GetWeakPtr()));
136 // TODO: Should we also schedule a task, in case there is not one scheduled? 182 // TODO: Should we also schedule a task, in case there is not one scheduled?
137 } 183 }
(...skipping 27 matching lines...) Expand all
165 } 211 }
166 212
167 void RequestCoordinator::RemoveRequestsCallback( 213 void RequestCoordinator::RemoveRequestsCallback(
168 const RequestQueue::UpdateMultipleRequestResults& results, 214 const RequestQueue::UpdateMultipleRequestResults& results,
169 const std::vector<SavePageRequest>& requests) { 215 const std::vector<SavePageRequest>& requests) {
170 for (SavePageRequest request : requests) 216 for (SavePageRequest request : requests)
171 NotifyCompleted(request, SavePageStatus::REMOVED); 217 NotifyCompleted(request, SavePageStatus::REMOVED);
172 } 218 }
173 219
174 void RequestCoordinator::StopProcessing() { 220 void RequestCoordinator::StopProcessing() {
175 is_canceled_ = true; 221 is_stopped_ = true;
176 if (offliner_ && is_busy_) { 222 StopPrerendering();
177 // TODO(dougarnett): Find current request and mark attempt aborted.
178 offliner_->Cancel();
179 }
180
181 // Stopping offliner means it will not call callback.
182 last_offlining_status_ =
183 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED;
184
185 if (active_request_) {
186 RecordOfflinerResultUMA(active_request_->client_id(),
187 last_offlining_status_);
188 active_request_.reset();
189 }
190 223
191 // Let the scheduler know we are done processing. 224 // Let the scheduler know we are done processing.
192 scheduler_callback_.Run(true); 225 scheduler_callback_.Run(true);
193 } 226 }
194 227
195 // Returns true if the caller should expect a callback, false otherwise. For 228 // Returns true if the caller should expect a callback, false otherwise. For
196 // instance, this would return false if a request is already in progress. 229 // instance, this would return false if a request is already in progress.
197 bool RequestCoordinator::StartProcessing( 230 bool RequestCoordinator::StartProcessing(
198 const DeviceConditions& device_conditions, 231 const DeviceConditions& device_conditions,
199 const base::Callback<void(bool)>& callback) { 232 const base::Callback<void(bool)>& callback) {
200 current_conditions_.reset(new DeviceConditions(device_conditions)); 233 current_conditions_.reset(new DeviceConditions(device_conditions));
201 if (is_busy_) return false; 234 if (is_busy_) return false;
202 235
203 // Mark the time at which we started processing so we can check our time 236 // Mark the time at which we started processing so we can check our time
204 // budget. 237 // budget.
205 operation_start_time_ = base::Time::Now(); 238 operation_start_time_ = base::Time::Now();
206 239
207 is_canceled_ = false; 240 is_stopped_ = false;
208 scheduler_callback_ = callback; 241 scheduler_callback_ = callback;
209 242
210 TryNextRequest(); 243 TryNextRequest();
211 244
212 return true; 245 return true;
213 } 246 }
214 247
215 void RequestCoordinator::TryNextRequest() { 248 void RequestCoordinator::TryNextRequest() {
216 // If there is no time left in the budget, return to the scheduler. 249 // If there is no time left in the budget, return to the scheduler.
217 // We do not remove the pending task that was set up earlier in case 250 // We do not remove the pending task that was set up earlier in case
(...skipping 27 matching lines...) Expand all
245 void RequestCoordinator::RequestQueueEmpty() { 278 void RequestCoordinator::RequestQueueEmpty() {
246 // Clear the outstanding "safety" task in the scheduler. 279 // Clear the outstanding "safety" task in the scheduler.
247 scheduler_->Unschedule(); 280 scheduler_->Unschedule();
248 // Let the scheduler know we are done processing. 281 // Let the scheduler know we are done processing.
249 scheduler_callback_.Run(true); 282 scheduler_callback_.Run(true);
250 } 283 }
251 284
252 void RequestCoordinator::SendRequestToOffliner(const SavePageRequest& request) { 285 void RequestCoordinator::SendRequestToOffliner(const SavePageRequest& request) {
253 // Check that offlining didn't get cancelled while performing some async 286 // Check that offlining didn't get cancelled while performing some async
254 // steps. 287 // steps.
255 if (is_canceled_) 288 if (is_stopped_)
256 return; 289 return;
257 290
258 GetOffliner(); 291 GetOffliner();
259 if (!offliner_) { 292 if (!offliner_) {
260 DVLOG(0) << "Unable to create Offliner. " 293 DVLOG(0) << "Unable to create Offliner. "
261 << "Cannot background offline page."; 294 << "Cannot background offline page.";
262 return; 295 return;
263 } 296 }
264 297
265 DCHECK(!is_busy_); 298 DCHECK(!is_busy_);
266 is_busy_ = true; 299 is_busy_ = true;
267 active_request_.reset(new SavePageRequest(request));
268 300
269 // Prepare an updated request to attempt. 301 // Prepare an updated request to attempt.
270 SavePageRequest updated_request(request); 302 SavePageRequest updated_request(request);
271 updated_request.MarkAttemptStarted(base::Time::Now()); 303 updated_request.MarkAttemptStarted(base::Time::Now());
304 active_request_.reset(new SavePageRequest(updated_request));
272 305
273 // Start the load and save process in the offliner (Async). 306 // Start the load and save process in the offliner (Async).
274 if (offliner_->LoadAndSave( 307 if (offliner_->LoadAndSave(
275 updated_request, base::Bind(&RequestCoordinator::OfflinerDoneCallback, 308 updated_request, base::Bind(&RequestCoordinator::OfflinerDoneCallback,
276 weak_ptr_factory_.GetWeakPtr()))) { 309 weak_ptr_factory_.GetWeakPtr()))) {
277 // Offliner accepted request so update it in the queue. 310 // Offliner accepted request so update it in the queue.
278 queue_->UpdateRequest(updated_request, 311 queue_->UpdateRequest(updated_request,
279 base::Bind(&RequestCoordinator::UpdateRequestCallback, 312 base::Bind(&RequestCoordinator::UpdateRequestCallback,
280 weak_ptr_factory_.GetWeakPtr(), 313 weak_ptr_factory_.GetWeakPtr(),
281 updated_request.client_id())); 314 updated_request.client_id()));
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 FOR_EACH_OBSERVER(Observer, observers_, OnChanged(request)); 438 FOR_EACH_OBSERVER(Observer, observers_, OnChanged(request));
406 } 439 }
407 440
408 void RequestCoordinator::GetOffliner() { 441 void RequestCoordinator::GetOffliner() {
409 if (!offliner_) { 442 if (!offliner_) {
410 offliner_ = factory_->GetOffliner(policy_.get()); 443 offliner_ = factory_->GetOffliner(policy_.get());
411 } 444 }
412 } 445 }
413 446
414 } // namespace offline_pages 447 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698