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

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

Issue 2219393004: Adds an observer for the request coordinator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@resumeAPI
Patch Set: Fix nits. 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"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 70
71 bool RequestCoordinator::SavePageLater( 71 bool RequestCoordinator::SavePageLater(
72 const GURL& url, const ClientId& client_id, bool user_requested) { 72 const GURL& url, const ClientId& client_id, bool user_requested) {
73 DVLOG(2) << "URL is " << url << " " << __func__; 73 DVLOG(2) << "URL is " << url << " " << __func__;
74 74
75 if (!OfflinePageModel::CanSaveURL(url)) { 75 if (!OfflinePageModel::CanSaveURL(url)) {
76 DVLOG(1) << "Not able to save page for requested url: " << url; 76 DVLOG(1) << "Not able to save page for requested url: " << url;
77 return false; 77 return false;
78 } 78 }
79 79
80 // TODO(petewil): We need a robust scheme for allocating new IDs. 80 // TODO(petewil): Use an int64_t random number for this, pass it to the
81 // offliner, and eventually use it as the offline_id - that way the client
82 // uses offline_id everywhere.
81 static int64_t id = 0; 83 static int64_t id = 0;
82 84
83 // Build a SavePageRequest. 85 // Build a SavePageRequest.
84 offline_pages::SavePageRequest request( 86 offline_pages::SavePageRequest request(
85 id++, url, client_id, base::Time::Now(), user_requested); 87 id++, url, client_id, base::Time::Now(), user_requested);
86 88
87 // Put the request on the request queue. 89 // Put the request on the request queue.
88 queue_->AddRequest(request, 90 queue_->AddRequest(request,
89 base::Bind(&RequestCoordinator::AddRequestResultCallback, 91 base::Bind(&RequestCoordinator::AddRequestResultCallback,
90 weak_ptr_factory_.GetWeakPtr())); 92 weak_ptr_factory_.GetWeakPtr()));
93 NotifyAdded(request);
91 return true; 94 return true;
92 } 95 }
93 void RequestCoordinator::GetAllRequests(const GetRequestsCallback& callback) { 96 void RequestCoordinator::GetAllRequests(const GetRequestsCallback& callback) {
94 // 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
95 // 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
96 // param set. 99 // param set.
97 queue_->GetRequests(base::Bind(&RequestCoordinator::GetQueuedRequestsCallback, 100 queue_->GetRequests(base::Bind(&RequestCoordinator::GetQueuedRequestsCallback,
98 weak_ptr_factory_.GetWeakPtr(), callback)); 101 weak_ptr_factory_.GetWeakPtr(), callback));
99 } 102 }
100 103
101 void RequestCoordinator::GetQueuedRequestsCallback( 104 void RequestCoordinator::GetQueuedRequestsCallback(
102 const GetRequestsCallback& callback, 105 const GetRequestsCallback& callback,
103 RequestQueue::GetRequestsResult result, 106 RequestQueue::GetRequestsResult result,
104 const std::vector<SavePageRequest>& requests) { 107 const std::vector<SavePageRequest>& requests) {
105 callback.Run(requests); 108 callback.Run(requests);
106 } 109 }
107 110
108 void RequestCoordinator::RemoveRequests( 111 void RequestCoordinator::RemoveRequests(
109 const std::vector<int64_t>& request_ids) { 112 const std::vector<int64_t>& request_ids) {
110 queue_->RemoveRequests(request_ids, 113 queue_->RemoveRequests(request_ids,
111 base::Bind(&RequestCoordinator::RemoveRequestsCallback, 114 base::Bind(&RequestCoordinator::RemoveRequestsCallback,
112 weak_ptr_factory_.GetWeakPtr())); 115 weak_ptr_factory_.GetWeakPtr()));
113 } 116 }
114 117
115 void RequestCoordinator::PauseRequests( 118 void RequestCoordinator::PauseRequests(
116 const std::vector<int64_t>& request_ids) { 119 const std::vector<int64_t>& request_ids) {
117 queue_->ChangeRequestsState( 120 queue_->ChangeRequestsState(
118 request_ids, SavePageRequest::RequestState::PAUSED, 121 request_ids, SavePageRequest::RequestState::PAUSED,
119 base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, 122 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback,
120 weak_ptr_factory_.GetWeakPtr())); 123 weak_ptr_factory_.GetWeakPtr()));
121 } 124 }
122 125
123 void RequestCoordinator::ResumeRequests( 126 void RequestCoordinator::ResumeRequests(
124 const std::vector<int64_t>& request_ids) { 127 const std::vector<int64_t>& request_ids) {
125 queue_->ChangeRequestsState( 128 queue_->ChangeRequestsState(
126 request_ids, SavePageRequest::RequestState::AVAILABLE, 129 request_ids, SavePageRequest::RequestState::AVAILABLE,
127 base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, 130 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback,
128 weak_ptr_factory_.GetWeakPtr())); 131 weak_ptr_factory_.GetWeakPtr()));
129 // TODO: Should we also schedule a task, in case there is not one scheduled? 132 // TODO: Should we also schedule a task, in case there is not one scheduled?
130 } 133 }
131 134
132 void RequestCoordinator::AddRequestResultCallback( 135 void RequestCoordinator::AddRequestResultCallback(
133 RequestQueue::AddRequestResult result, 136 RequestQueue::AddRequestResult result,
134 const SavePageRequest& request) { 137 const SavePageRequest& request) {
135
136 // Inform the scheduler that we have an outstanding task.. 138 // Inform the scheduler that we have an outstanding task..
137 scheduler_->Schedule(GetTriggerConditionsForUserRequest()); 139 scheduler_->Schedule(GetTriggerConditionsForUserRequest());
138 } 140 }
139 141
140 // Called in response to updating a request in the request queue. 142 // Called in response to updating a request in the request queue.
141 void RequestCoordinator::UpdateRequestCallback( 143 void RequestCoordinator::UpdateRequestCallback(
142 const ClientId& client_id, 144 const ClientId& client_id,
143 RequestQueue::UpdateRequestResult result) { 145 RequestQueue::UpdateRequestResult result) {
144 // If the request succeeded, nothing to do. If it failed, we can't really do 146 // If the request succeeded, nothing to do. If it failed, we can't really do
145 // much, so just log it. 147 // much, so just log it.
146 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { 148 if (result != RequestQueue::UpdateRequestResult::SUCCESS) {
147 DVLOG(1) << "Failed to update request attempt details. " 149 DVLOG(1) << "Failed to update request attempt details. "
148 << static_cast<int>(result); 150 << static_cast<int>(result);
149 event_logger_.RecordUpdateRequestFailed(client_id.name_space, result); 151 event_logger_.RecordUpdateRequestFailed(client_id.name_space, result);
150 } 152 }
151 } 153 }
152 154
153 // Called in response to updating multiple requests in the request queue. 155 // Called in response to updating multiple requests in the request queue.
154 void RequestCoordinator::UpdateMultipleRequestCallback( 156 void RequestCoordinator::UpdateMultipleRequestsCallback(
155 RequestQueue::UpdateRequestResult result) { 157 const RequestQueue::UpdateMultipleRequestResults& results,
156 // If the request succeeded, nothing to do. If it failed, we can't really do 158 const std::vector<SavePageRequest>& requests) {
157 // much, so just log it. 159 for (SavePageRequest request : requests)
158 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { 160 NotifyChanged(request);
159 DVLOG(1) << "Failed to update request attempt details. "
160 << static_cast<int>(result);
161 }
162 } 161 }
163 162
164 void RequestCoordinator::RemoveRequestsCallback( 163 void RequestCoordinator::RemoveRequestsCallback(
165 const RequestQueue::UpdateMultipleRequestResults& results) { 164 const RequestQueue::UpdateMultipleRequestResults& results,
166 // TODO(petewil): Today the RemoveRequests API does not come with a callback. 165 const std::vector<SavePageRequest>& requests) {
167 // Should we add one? Perhaps the notifications from the observer will be 166 for (SavePageRequest request : requests)
168 // sufficient. 167 NotifyRemoved(request);
169 } 168 }
170 169
171 void RequestCoordinator::StopProcessing() { 170 void RequestCoordinator::StopProcessing() {
172 is_canceled_ = true; 171 is_canceled_ = true;
173 if (offliner_ && is_busy_) { 172 if (offliner_ && is_busy_) {
174 // TODO(dougarnett): Find current request and mark attempt aborted. 173 // TODO(dougarnett): Find current request and mark attempt aborted.
175 offliner_->Cancel(); 174 offliner_->Cancel();
176 } 175 }
177 176
178 // Stopping offliner means it will not call callback. 177 // Stopping offliner means it will not call callback.
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) { 305 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) {
307 // Update the request for the canceled attempt. 306 // Update the request for the canceled attempt.
308 // TODO(dougarnett): See if we can conclusively identify other attempt 307 // TODO(dougarnett): See if we can conclusively identify other attempt
309 // aborted cases to treat this way (eg, for Render Process Killed). 308 // aborted cases to treat this way (eg, for Render Process Killed).
310 SavePageRequest updated_request(request); 309 SavePageRequest updated_request(request);
311 updated_request.MarkAttemptAborted(); 310 updated_request.MarkAttemptAborted();
312 queue_->UpdateRequest(updated_request, 311 queue_->UpdateRequest(updated_request,
313 base::Bind(&RequestCoordinator::UpdateRequestCallback, 312 base::Bind(&RequestCoordinator::UpdateRequestCallback,
314 weak_ptr_factory_.GetWeakPtr(), 313 weak_ptr_factory_.GetWeakPtr(),
315 updated_request.client_id())); 314 updated_request.client_id()));
315 NotifyFailed(updated_request, SavePageStatus::FOREGROUND_CANCELED);
316 316
317 } else if (status == Offliner::RequestStatus::SAVED || 317 } else if (status == Offliner::RequestStatus::SAVED) {
318 request.completed_attempt_count() + 1 >= 318 // Remove the request from the queue if it succeeded.
319 policy_->GetMaxCompletedTries()) {
320 // Remove the request from the queue if it either succeeded or exceeded the
321 // max number of retries. The +1 represents the request that just
322 // completed. Since we call MarkAttemptCompleted within the if branches,
323 // the completed_attempt_count has not yet been updated when we are checking
324 // the if condition.
325 std::vector<int64_t> remove_requests; 319 std::vector<int64_t> remove_requests;
326 remove_requests.push_back(request.request_id()); 320 remove_requests.push_back(request.request_id());
327 queue_->RemoveRequests( 321 queue_->RemoveRequests(
328 remove_requests, base::Bind(&RequestCoordinator::RemoveRequestsCallback, 322 remove_requests, base::Bind(&RequestCoordinator::RemoveRequestsCallback,
329 weak_ptr_factory_.GetWeakPtr())); 323 weak_ptr_factory_.GetWeakPtr()));
324 NotifySucceeded(request);
325 } else if (request.completed_attempt_count() + 1 >=
326 policy_->GetMaxCompletedTries()) {
327 // Remove from the request queue if we exceeeded max retries. The +1
328 // represents the request that just completed. Since we call
329 // MarkAttemptCompleted within the if branches, the completed_attempt_count
330 // has not yet been updated when we are checking the if condition.
331 std::vector<int64_t> remove_requests;
332 remove_requests.push_back(request.request_id());
333 queue_->RemoveRequests(
334 remove_requests, base::Bind(&RequestCoordinator::RemoveRequestsCallback,
335 weak_ptr_factory_.GetWeakPtr()));
336 NotifyFailed(request, SavePageStatus::RETRY_COUNT_EXCEEDED);
330 } else { 337 } else {
331 // If we failed, but are not over the limit, update the request in the 338 // If we failed, but are not over the limit, update the request in the
332 // queue. 339 // queue.
333 SavePageRequest updated_request(request); 340 SavePageRequest updated_request(request);
334 updated_request.MarkAttemptCompleted(); 341 updated_request.MarkAttemptCompleted();
335 queue_->UpdateRequest(updated_request, 342 queue_->UpdateRequest(updated_request,
336 base::Bind(&RequestCoordinator::UpdateRequestCallback, 343 base::Bind(&RequestCoordinator::UpdateRequestCallback,
337 weak_ptr_factory_.GetWeakPtr(), 344 weak_ptr_factory_.GetWeakPtr(),
338 updated_request.client_id())); 345 updated_request.client_id()));
346 NotifyChanged(updated_request);
339 } 347 }
340 348
341 // Determine whether we might try another request in this 349 // Determine whether we might try another request in this
342 // processing window based on how the previous request completed. 350 // processing window based on how the previous request completed.
343 // 351 //
344 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate 352 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate
345 // codes as to whether we should try another request or not. 353 // codes as to whether we should try another request or not.
346 switch (status) { 354 switch (status) {
347 case Offliner::RequestStatus::SAVED: 355 case Offliner::RequestStatus::SAVED:
348 case Offliner::RequestStatus::SAVE_FAILED: 356 case Offliner::RequestStatus::SAVE_FAILED:
(...skipping 15 matching lines...) Expand all
364 372
365 const Scheduler::TriggerConditions 373 const Scheduler::TriggerConditions
366 RequestCoordinator::GetTriggerConditionsForUserRequest() { 374 RequestCoordinator::GetTriggerConditionsForUserRequest() {
367 Scheduler::TriggerConditions trigger_conditions( 375 Scheduler::TriggerConditions trigger_conditions(
368 policy_->PowerRequiredForUserRequestedPage(), 376 policy_->PowerRequiredForUserRequestedPage(),
369 policy_->BatteryPercentageRequiredForUserRequestedPage(), 377 policy_->BatteryPercentageRequiredForUserRequestedPage(),
370 policy_->UnmeteredNetworkRequiredForUserRequestedPage()); 378 policy_->UnmeteredNetworkRequiredForUserRequestedPage());
371 return trigger_conditions; 379 return trigger_conditions;
372 } 380 }
373 381
382 void RequestCoordinator::AddObserver(Observer* observer) {
383 DCHECK(observer);
384 observers_.AddObserver(observer);
385 }
386
387 void RequestCoordinator::RemoveObserver(Observer* observer) {
388 observers_.RemoveObserver(observer);
389 }
390
391 void RequestCoordinator::NotifyAdded(const SavePageRequest& request) {
392 FOR_EACH_OBSERVER(Observer, observers_, OnAdded(request));
393 }
394
395 void RequestCoordinator::NotifySucceeded(const SavePageRequest& request) {
396 FOR_EACH_OBSERVER(Observer, observers_, OnSucceeded(request));
397 }
398
399 void RequestCoordinator::NotifyFailed(const SavePageRequest& request,
400 SavePageStatus status) {
401 FOR_EACH_OBSERVER(Observer, observers_, OnFailed(request, status));
402 }
403
404 void RequestCoordinator::NotifyChanged(const SavePageRequest& request) {
405 FOR_EACH_OBSERVER(Observer, observers_, OnChanged(request));
406 }
407
408 void RequestCoordinator::NotifyRemoved(const SavePageRequest& request) {
409 FOR_EACH_OBSERVER(Observer, observers_,
410 OnRemoved(request, SavePageStatus::REMOVED_BY_CLIENT));
411 }
412
374 void RequestCoordinator::GetOffliner() { 413 void RequestCoordinator::GetOffliner() {
375 if (!offliner_) { 414 if (!offliner_) {
376 offliner_ = factory_->GetOffliner(policy_.get()); 415 offliner_ = factory_->GetOffliner(policy_.get());
377 } 416 }
378 } 417 }
379 418
380 } // namespace offline_pages 419 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698