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

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: CR feedback per Dimich - Changed return values 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) {
fgorski 2016/08/15 17:51:44 nit: remove {}
Pete Williamson 2016/08/15 20:22:52 Done.
158 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { 160 NotifyChanged(request);
159 DVLOG(1) << "Failed to update request attempt details. "
160 << static_cast<int>(result);
161 } 161 }
162 } 162 }
163 163
164 void RequestCoordinator::RemoveRequestsCallback( 164 void RequestCoordinator::RemoveRequestsCallback(
165 const RequestQueue::UpdateMultipleRequestResults& results) { 165 const RequestQueue::UpdateMultipleRequestResults& results,
166 // TODO(petewil): Today the RemoveRequests API does not come with a callback. 166 const std::vector<SavePageRequest>& requests) {
167 // Should we add one? Perhaps the notifications from the observer will be 167 for (SavePageRequest request : requests) {
fgorski 2016/08/15 17:51:44 nit: remove {}
Pete Williamson 2016/08/15 20:22:52 Done.
168 // sufficient. 168 NotifyRemoved(request);
169 }
169 } 170 }
170 171
171 void RequestCoordinator::StopProcessing() { 172 void RequestCoordinator::StopProcessing() {
172 is_canceled_ = true; 173 is_canceled_ = true;
173 if (offliner_ && is_busy_) { 174 if (offliner_ && is_busy_) {
174 // TODO(dougarnett): Find current request and mark attempt aborted. 175 // TODO(dougarnett): Find current request and mark attempt aborted.
175 offliner_->Cancel(); 176 offliner_->Cancel();
176 } 177 }
177 178
178 // Stopping offliner means it will not call callback. 179 // 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) { 307 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) {
307 // Update the request for the canceled attempt. 308 // Update the request for the canceled attempt.
308 // TODO(dougarnett): See if we can conclusively identify other attempt 309 // TODO(dougarnett): See if we can conclusively identify other attempt
309 // aborted cases to treat this way (eg, for Render Process Killed). 310 // aborted cases to treat this way (eg, for Render Process Killed).
310 SavePageRequest updated_request(request); 311 SavePageRequest updated_request(request);
311 updated_request.MarkAttemptAborted(); 312 updated_request.MarkAttemptAborted();
312 queue_->UpdateRequest(updated_request, 313 queue_->UpdateRequest(updated_request,
313 base::Bind(&RequestCoordinator::UpdateRequestCallback, 314 base::Bind(&RequestCoordinator::UpdateRequestCallback,
314 weak_ptr_factory_.GetWeakPtr(), 315 weak_ptr_factory_.GetWeakPtr(),
315 updated_request.client_id())); 316 updated_request.client_id()));
317 NotifyFailed(updated_request, SavePageStatus::FOREGROUND_CANCELED);
316 318
317 } else if (status == Offliner::RequestStatus::SAVED || 319 } else if (status == Offliner::RequestStatus::SAVED) {
318 request.completed_attempt_count() + 1 >= 320 // 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; 321 std::vector<int64_t> remove_requests;
326 remove_requests.push_back(request.request_id()); 322 remove_requests.push_back(request.request_id());
327 queue_->RemoveRequests( 323 queue_->RemoveRequests(
328 remove_requests, base::Bind(&RequestCoordinator::RemoveRequestsCallback, 324 remove_requests, base::Bind(&RequestCoordinator::RemoveRequestsCallback,
329 weak_ptr_factory_.GetWeakPtr())); 325 weak_ptr_factory_.GetWeakPtr()));
326 NotifySucceeded(request);
327 } else if (request.completed_attempt_count() + 1 >=
328 policy_->GetMaxCompletedTries()) {
329 // Remove from the request queue if we exceeeded max retries. The +1
330 // represents the request that just completed. Since we call
331 // MarkAttemptCompleted within the if branches, the completed_attempt_count
332 // has not yet been updated when we are checking the if condition.
333 std::vector<int64_t> remove_requests;
334 remove_requests.push_back(request.request_id());
335 queue_->RemoveRequests(
336 remove_requests, base::Bind(&RequestCoordinator::RemoveRequestsCallback,
337 weak_ptr_factory_.GetWeakPtr()));
338 NotifyFailed(request, SavePageStatus::RETRY_COUNT_EXCEEDED);
330 } else { 339 } else {
331 // If we failed, but are not over the limit, update the request in the 340 // If we failed, but are not over the limit, update the request in the
332 // queue. 341 // queue.
333 SavePageRequest updated_request(request); 342 SavePageRequest updated_request(request);
334 updated_request.MarkAttemptCompleted(); 343 updated_request.MarkAttemptCompleted();
335 queue_->UpdateRequest(updated_request, 344 queue_->UpdateRequest(updated_request,
336 base::Bind(&RequestCoordinator::UpdateRequestCallback, 345 base::Bind(&RequestCoordinator::UpdateRequestCallback,
337 weak_ptr_factory_.GetWeakPtr(), 346 weak_ptr_factory_.GetWeakPtr(),
338 updated_request.client_id())); 347 updated_request.client_id()));
348 NotifyChanged(updated_request);
339 } 349 }
340 350
341 // Determine whether we might try another request in this 351 // Determine whether we might try another request in this
342 // processing window based on how the previous request completed. 352 // processing window based on how the previous request completed.
343 // 353 //
344 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate 354 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate
345 // codes as to whether we should try another request or not. 355 // codes as to whether we should try another request or not.
346 switch (status) { 356 switch (status) {
347 case Offliner::RequestStatus::SAVED: 357 case Offliner::RequestStatus::SAVED:
348 case Offliner::RequestStatus::SAVE_FAILED: 358 case Offliner::RequestStatus::SAVE_FAILED:
(...skipping 15 matching lines...) Expand all
364 374
365 const Scheduler::TriggerConditions 375 const Scheduler::TriggerConditions
366 RequestCoordinator::GetTriggerConditionsForUserRequest() { 376 RequestCoordinator::GetTriggerConditionsForUserRequest() {
367 Scheduler::TriggerConditions trigger_conditions( 377 Scheduler::TriggerConditions trigger_conditions(
368 policy_->PowerRequiredForUserRequestedPage(), 378 policy_->PowerRequiredForUserRequestedPage(),
369 policy_->BatteryPercentageRequiredForUserRequestedPage(), 379 policy_->BatteryPercentageRequiredForUserRequestedPage(),
370 policy_->UnmeteredNetworkRequiredForUserRequestedPage()); 380 policy_->UnmeteredNetworkRequiredForUserRequestedPage());
371 return trigger_conditions; 381 return trigger_conditions;
372 } 382 }
373 383
384 void RequestCoordinator::AddObserver(Observer* observer) {
385 DCHECK(observer);
386 observers_.AddObserver(observer);
387 }
388
389 void RequestCoordinator::RemoveObserver(Observer* observer) {
390 observers_.RemoveObserver(observer);
391 }
392
393 void RequestCoordinator::NotifyAdded(const SavePageRequest& request) {
394 FOR_EACH_OBSERVER(Observer, observers_, OnAdded(request));
395 }
396
397 void RequestCoordinator::NotifySucceeded(const SavePageRequest& request) {
398 FOR_EACH_OBSERVER(Observer, observers_, OnSucceeded(request));
399 }
400
401 void RequestCoordinator::NotifyFailed(const SavePageRequest& request,
402 SavePageStatus status) {
403 FOR_EACH_OBSERVER(Observer, observers_, OnFailed(request, status));
404 }
405
406 void RequestCoordinator::NotifyChanged(const SavePageRequest& request) {
407 FOR_EACH_OBSERVER(Observer, observers_, OnChanged(request));
408 }
409
410 void RequestCoordinator::NotifyRemoved(const SavePageRequest& request) {
411 FOR_EACH_OBSERVER(Observer, observers_,
412 OnRemoved(request, SavePageStatus::REMOVED_BY_CLIENT));
413 }
414
374 void RequestCoordinator::GetOffliner() { 415 void RequestCoordinator::GetOffliner() {
375 if (!offliner_) { 416 if (!offliner_) {
376 offliner_ = factory_->GetOffliner(policy_.get()); 417 offliner_ = factory_->GetOffliner(policy_.get());
377 } 418 }
378 } 419 }
379 420
380 } // namespace offline_pages 421 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698