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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 static int64_t id = 0; | 81 static int64_t id = 0; |
82 | 82 |
83 // Build a SavePageRequest. | 83 // Build a SavePageRequest. |
84 offline_pages::SavePageRequest request( | 84 offline_pages::SavePageRequest request( |
85 id++, url, client_id, base::Time::Now(), user_requested); | 85 id++, url, client_id, base::Time::Now(), user_requested); |
86 | 86 |
87 // Put the request on the request queue. | 87 // Put the request on the request queue. |
88 queue_->AddRequest(request, | 88 queue_->AddRequest(request, |
89 base::Bind(&RequestCoordinator::AddRequestResultCallback, | 89 base::Bind(&RequestCoordinator::AddRequestResultCallback, |
90 weak_ptr_factory_.GetWeakPtr())); | 90 weak_ptr_factory_.GetWeakPtr())); |
91 NotifyAdded(request); | |
91 return true; | 92 return true; |
92 } | 93 } |
93 void RequestCoordinator::GetQueuedRequests( | 94 void RequestCoordinator::GetQueuedRequests( |
94 const std::string& client_namespace, | 95 const std::string& client_namespace, |
95 const QueuedRequestCallback& callback) { | 96 const QueuedRequestCallback& callback) { |
96 // Get all matching requests from the request queue, send them to our | 97 // Get all matching requests from the request queue, send them to our |
97 // callback. We bind the namespace and callback to the front of the callback | 98 // callback. We bind the namespace and callback to the front of the callback |
98 // param set. | 99 // param set. |
99 queue_->GetRequests(base::Bind(&RequestCoordinator::GetQueuedRequestsCallback, | 100 queue_->GetRequests(base::Bind(&RequestCoordinator::GetQueuedRequestsCallback, |
100 weak_ptr_factory_.GetWeakPtr(), | 101 weak_ptr_factory_.GetWeakPtr(), |
(...skipping 22 matching lines...) Expand all Loading... | |
123 client_ids, base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, | 124 client_ids, base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, |
124 weak_ptr_factory_.GetWeakPtr())); | 125 weak_ptr_factory_.GetWeakPtr())); |
125 } | 126 } |
126 | 127 |
127 void RequestCoordinator::PauseRequests( | 128 void RequestCoordinator::PauseRequests( |
128 const std::vector<int64_t>& request_ids) { | 129 const std::vector<int64_t>& request_ids) { |
129 queue_->PauseRequests( | 130 queue_->PauseRequests( |
130 request_ids, | 131 request_ids, |
131 base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, | 132 base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, |
132 weak_ptr_factory_.GetWeakPtr())); | 133 weak_ptr_factory_.GetWeakPtr())); |
134 SendNotifyChangeForRequestIdList(request_ids); | |
fgorski
2016/08/10 21:30:44
I think that should be happening in the callback.
Pete Williamson
2016/08/11 00:08:36
Done.
| |
133 } | 135 } |
134 | 136 |
135 void RequestCoordinator::ResumeRequests( | 137 void RequestCoordinator::ResumeRequests( |
136 const std::vector<int64_t>& request_ids) { | 138 const std::vector<int64_t>& request_ids) { |
137 queue_->ResumeRequests( | 139 queue_->ResumeRequests( |
138 request_ids, | 140 request_ids, |
139 base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, | 141 base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, |
140 weak_ptr_factory_.GetWeakPtr())); | 142 weak_ptr_factory_.GetWeakPtr())); |
141 // TODO: Should we also schedule a task, in case there is not one scheduled? | 143 // TODO: Should we also schedule a task, in case there is not one scheduled? |
144 SendNotifyChangeForRequestIdList(request_ids); | |
fgorski
2016/08/10 21:30:44
same
Pete Williamson
2016/08/11 00:08:36
Done.
| |
142 } | 145 } |
143 | 146 |
144 void RequestCoordinator::AddRequestResultCallback( | 147 void RequestCoordinator::AddRequestResultCallback( |
145 RequestQueue::AddRequestResult result, | 148 RequestQueue::AddRequestResult result, |
146 const SavePageRequest& request) { | 149 const SavePageRequest& request) { |
147 | |
148 // Inform the scheduler that we have an outstanding task.. | 150 // Inform the scheduler that we have an outstanding task.. |
149 scheduler_->Schedule(GetTriggerConditionsForUserRequest()); | 151 scheduler_->Schedule(GetTriggerConditionsForUserRequest()); |
150 } | 152 } |
151 | 153 |
152 // Called in response to updating a request in the request queue. | 154 // Called in response to updating a request in the request queue. |
153 void RequestCoordinator::UpdateRequestCallback( | 155 void RequestCoordinator::UpdateRequestCallback( |
154 const ClientId& client_id, | 156 const ClientId& client_id, |
155 RequestQueue::UpdateRequestResult result) { | 157 RequestQueue::UpdateRequestResult result) { |
156 // If the request succeeded, nothing to do. If it failed, we can't really do | 158 // If the request succeeded, nothing to do. If it failed, we can't really do |
157 // much, so just log it. | 159 // much, so just log it. |
158 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { | 160 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { |
159 DVLOG(1) << "Failed to update request attempt details. " | 161 DVLOG(1) << "Failed to update request attempt details. " |
160 << static_cast<int>(result); | 162 << static_cast<int>(result); |
161 event_logger_.RecordUpdateRequestFailed(client_id.name_space, result); | 163 event_logger_.RecordUpdateRequestFailed(client_id.name_space, result); |
162 } | 164 } |
163 } | 165 } |
164 | 166 |
165 // Called in response to updating multiple requests in the request queue. | 167 // Called in response to updating multiple requests in the request queue. |
166 void RequestCoordinator::UpdateMultipleRequestCallback( | 168 void RequestCoordinator::UpdateMultipleRequestCallback( |
167 RequestQueue::UpdateRequestResult result) { | 169 RequestQueue::UpdateRequestResult result) { |
168 // If the request succeeded, nothing to do. If it failed, we can't really do | 170 // If the request succeeded, nothing to do. If it failed, we can't really do |
169 // much, so just log it. | 171 // much, so just log it. |
170 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { | 172 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { |
171 DVLOG(1) << "Failed to update request attempt details. " | 173 DVLOG(1) << "Failed to update request attempt details. " |
172 << static_cast<int>(result); | 174 << static_cast<int>(result); |
173 } | 175 } |
174 } | 176 } |
175 | 177 |
178 // Called in response to updating multiple requests in the request queue. | |
179 void RequestCoordinator::NotifyChangedListCallback( | |
180 const std::vector<int64_t> request_ids, | |
181 RequestQueue::GetRequestsResult result, | |
182 const std::vector<SavePageRequest>& requests) { | |
183 std::vector<ClientId> client_ids; | |
184 | |
185 // For each item in request_ids, find it in requests and send a changed | |
186 // notification for that request. | |
187 for (const SavePageRequest& request : requests) { | |
188 // If we find a match, send a notification. | |
189 for (int64_t request_id : request_ids) { | |
fgorski
2016/08/10 21:30:44
given the structure of this loop, wouldn't std::un
Pete Williamson
2016/08/11 00:08:36
Done.
| |
190 if (request_id == request.request_id()) { | |
191 NotifyChanged(request); | |
192 break; | |
193 } | |
194 } | |
195 } | |
196 } | |
197 | |
198 | |
176 void RequestCoordinator::StopProcessing() { | 199 void RequestCoordinator::StopProcessing() { |
177 is_canceled_ = true; | 200 is_canceled_ = true; |
178 if (offliner_ && is_busy_) { | 201 if (offliner_ && is_busy_) { |
179 // TODO(dougarnett): Find current request and mark attempt aborted. | 202 // TODO(dougarnett): Find current request and mark attempt aborted. |
180 offliner_->Cancel(); | 203 offliner_->Cancel(); |
181 } | 204 } |
182 | 205 |
183 // Stopping offliner means it will not call callback. | 206 // Stopping offliner means it will not call callback. |
184 last_offlining_status_ = | 207 last_offlining_status_ = |
185 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED; | 208 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) { | 334 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) { |
312 // Update the request for the canceled attempt. | 335 // Update the request for the canceled attempt. |
313 // TODO(dougarnett): See if we can conclusively identify other attempt | 336 // TODO(dougarnett): See if we can conclusively identify other attempt |
314 // aborted cases to treat this way (eg, for Render Process Killed). | 337 // aborted cases to treat this way (eg, for Render Process Killed). |
315 SavePageRequest updated_request(request); | 338 SavePageRequest updated_request(request); |
316 updated_request.MarkAttemptAborted(); | 339 updated_request.MarkAttemptAborted(); |
317 queue_->UpdateRequest(updated_request, | 340 queue_->UpdateRequest(updated_request, |
318 base::Bind(&RequestCoordinator::UpdateRequestCallback, | 341 base::Bind(&RequestCoordinator::UpdateRequestCallback, |
319 weak_ptr_factory_.GetWeakPtr(), | 342 weak_ptr_factory_.GetWeakPtr(), |
320 updated_request.client_id())); | 343 updated_request.client_id())); |
344 NotifyFailed(updated_request, static_cast<int64_t>(status)); | |
fgorski
2016/08/10 21:30:44
If we are returning offliner status, let's not pas
Pete Williamson
2016/08/11 00:08:36
Done.
| |
321 | 345 |
322 } else if (status == Offliner::RequestStatus::SAVED || | 346 } else if (status == Offliner::RequestStatus::SAVED) { |
323 request.completed_attempt_count() + 1 >= | 347 // Remove the request from the queue if it succeeded. |
324 policy_->GetMaxCompletedTries()) { | |
325 // Remove the request from the queue if it either succeeded or exceeded the | |
326 // max number of retries. The +1 represents the request that just | |
327 // completed. Since we call MarkAttemptCompleted within the if branches, | |
328 // the completed_attempt_count has not yet been updated when we are checking | |
329 // the if condition. | |
330 queue_->RemoveRequest( | 348 queue_->RemoveRequest( |
331 request.request_id(), | 349 request.request_id(), |
332 base::Bind(&RequestCoordinator::UpdateRequestCallback, | 350 base::Bind(&RequestCoordinator::UpdateRequestCallback, |
333 weak_ptr_factory_.GetWeakPtr(), request.client_id())); | 351 weak_ptr_factory_.GetWeakPtr(), request.client_id())); |
352 // TODO: We don't have an offline ID to return. Modify the prerenderer | |
353 // callback to pass it. | |
354 NotifySucceeded(request, 0); | |
355 } else if (request.completed_attempt_count() + 1 >= | |
356 policy_->GetMaxCompletedTries()) { | |
357 // Remove from the request queue if we exceeeded max retries. The +1 | |
358 // represents the request that just completed. Since we call | |
359 // MarkAttemptCompleted within the if branches, the completed_attempt_count | |
360 // has not yet been updated when we are checking the if condition. | |
361 queue_->RemoveRequest( | |
362 request.request_id(), | |
363 base::Bind(&RequestCoordinator::UpdateRequestCallback, | |
364 weak_ptr_factory_.GetWeakPtr(), request.client_id())); | |
365 NotifyFailed(request, static_cast<int64_t>(status)); | |
334 } else { | 366 } else { |
335 // If we failed, but are not over the limit, update the request in the | 367 // If we failed, but are not over the limit, update the request in the |
336 // queue. | 368 // queue. |
337 SavePageRequest updated_request(request); | 369 SavePageRequest updated_request(request); |
338 updated_request.MarkAttemptCompleted(); | 370 updated_request.MarkAttemptCompleted(); |
339 queue_->UpdateRequest(updated_request, | 371 queue_->UpdateRequest(updated_request, |
340 base::Bind(&RequestCoordinator::UpdateRequestCallback, | 372 base::Bind(&RequestCoordinator::UpdateRequestCallback, |
341 weak_ptr_factory_.GetWeakPtr(), | 373 weak_ptr_factory_.GetWeakPtr(), |
342 updated_request.client_id())); | 374 updated_request.client_id())); |
375 NotifyChanged(updated_request); | |
343 } | 376 } |
344 | 377 |
345 // Determine whether we might try another request in this | 378 // Determine whether we might try another request in this |
346 // processing window based on how the previous request completed. | 379 // processing window based on how the previous request completed. |
347 // | 380 // |
348 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate | 381 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate |
349 // codes as to whether we should try another request or not. | 382 // codes as to whether we should try another request or not. |
350 switch (status) { | 383 switch (status) { |
351 case Offliner::RequestStatus::SAVED: | 384 case Offliner::RequestStatus::SAVED: |
352 case Offliner::RequestStatus::SAVE_FAILED: | 385 case Offliner::RequestStatus::SAVE_FAILED: |
(...skipping 15 matching lines...) Expand all Loading... | |
368 | 401 |
369 const Scheduler::TriggerConditions | 402 const Scheduler::TriggerConditions |
370 RequestCoordinator::GetTriggerConditionsForUserRequest() { | 403 RequestCoordinator::GetTriggerConditionsForUserRequest() { |
371 Scheduler::TriggerConditions trigger_conditions( | 404 Scheduler::TriggerConditions trigger_conditions( |
372 policy_->PowerRequiredForUserRequestedPage(), | 405 policy_->PowerRequiredForUserRequestedPage(), |
373 policy_->BatteryPercentageRequiredForUserRequestedPage(), | 406 policy_->BatteryPercentageRequiredForUserRequestedPage(), |
374 policy_->UnmeteredNetworkRequiredForUserRequestedPage()); | 407 policy_->UnmeteredNetworkRequiredForUserRequestedPage()); |
375 return trigger_conditions; | 408 return trigger_conditions; |
376 } | 409 } |
377 | 410 |
411 void RequestCoordinator::AddObserver(Observer* observer) { | |
412 DCHECK(observer); | |
413 observers_.AddObserver(observer); | |
414 } | |
415 | |
416 void RequestCoordinator::RemoveObserver(Observer* observer) { | |
417 observers_.RemoveObserver(observer); | |
418 } | |
419 | |
420 void RequestCoordinator::NotifyAdded(const SavePageRequest& request) { | |
421 FOR_EACH_OBSERVER(Observer, observers_, OnAdded(request)); | |
422 } | |
423 | |
424 void RequestCoordinator::NotifySucceeded( | |
425 const SavePageRequest& request, int64_t offline_id) { | |
426 FOR_EACH_OBSERVER(Observer, observers_, OnSucceeded(request, offline_id)); | |
427 } | |
428 | |
429 void RequestCoordinator::NotifyFailed( | |
430 const SavePageRequest& request, int64_t failure_code) { | |
431 FOR_EACH_OBSERVER(Observer, observers_, OnFailed(request, failure_code)); | |
432 } | |
433 | |
434 void RequestCoordinator::NotifyChanged(const SavePageRequest& request) { | |
435 FOR_EACH_OBSERVER(Observer, observers_, OnChanged(request)); | |
436 } | |
437 | |
438 void RequestCoordinator::SendNotifyChangeForRequestIdList( | |
439 const std::vector<int64_t> request_ids) { | |
440 // Bind the request_ids onto our callback parameter list, the work will be | |
441 // done in the callback. | |
442 queue_->GetRequests(base::Bind(&RequestCoordinator::NotifyChangedListCallback, | |
443 weak_ptr_factory_.GetWeakPtr(), | |
444 request_ids)); | |
445 } | |
446 | |
378 void RequestCoordinator::GetOffliner() { | 447 void RequestCoordinator::GetOffliner() { |
379 if (!offliner_) { | 448 if (!offliner_) { |
380 offliner_ = factory_->GetOffliner(policy_.get()); | 449 offliner_ = factory_->GetOffliner(policy_.get()); |
381 } | 450 } |
382 } | 451 } |
383 | 452 |
384 } // namespace offline_pages | 453 } // namespace offline_pages |
OLD | NEW |