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

Side by Side Diff: content/browser/background_fetch/background_fetch_data_manager.cc

Issue 2796933003: Store BackgroundFetchRequestInfo in a refcounted pointer (Closed)
Patch Set: Created 3 years, 8 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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 "content/browser/background_fetch/background_fetch_data_manager.h" 5 #include "content/browser/background_fetch/background_fetch_data_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <queue> 8 #include <queue>
9 9
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 12 matching lines...) Expand all
23 // Background Fetch registration. This roughly matches the on-disk format that 23 // Background Fetch registration. This roughly matches the on-disk format that
24 // will be adhered to in the future. 24 // will be adhered to in the future.
25 class BackgroundFetchDataManager::RegistrationData { 25 class BackgroundFetchDataManager::RegistrationData {
26 public: 26 public:
27 RegistrationData(const std::vector<ServiceWorkerFetchRequest>& requests, 27 RegistrationData(const std::vector<ServiceWorkerFetchRequest>& requests,
28 const BackgroundFetchOptions& options) 28 const BackgroundFetchOptions& options)
29 : options_(options) { 29 : options_(options) {
30 int request_index = 0; 30 int request_index = 0;
31 31
32 // Convert the given |requests| to BackgroundFetchRequestInfo objects. 32 // Convert the given |requests| to BackgroundFetchRequestInfo objects.
33 for (const ServiceWorkerFetchRequest& request : requests) 33 for (const ServiceWorkerFetchRequest& fetch_request : requests) {
34 pending_requests_.emplace(request_index++, request); 34 scoped_refptr<BackgroundFetchRequestInfo> request =
35 new BackgroundFetchRequestInfo(request_index++, fetch_request);
36
37 pending_requests_.push(std::move(request));
38 }
35 } 39 }
36 40
37 ~RegistrationData() = default; 41 ~RegistrationData() = default;
38 42
39 // Returns whether there are remaining requests on the request queue. 43 // Returns whether there are remaining requests on the request queue.
40 bool HasPendingRequests() const { return !pending_requests_.empty(); } 44 bool HasPendingRequests() const { return !pending_requests_.empty(); }
41 45
42 // Consumes a request from the queue that is to be fetched. 46 // Consumes a request from the queue that is to be fetched.
43 BackgroundFetchRequestInfo GetPendingRequest() { 47 scoped_refptr<BackgroundFetchRequestInfo> GetPendingRequest() {
44 DCHECK(!pending_requests_.empty()); 48 DCHECK(!pending_requests_.empty());
45 49
46 BackgroundFetchRequestInfo request = pending_requests_.front(); 50 auto request = pending_requests_.front();
47 pending_requests_.pop(); 51 pending_requests_.pop();
48 52
49 // The |request| is considered to be active now. 53 // The |request| is considered to be active now.
50 active_requests_.push_back(request); 54 active_requests_.push_back(request);
51 55
52 return request; 56 return request;
53 } 57 }
54 58
55 // Marks the |request| as having started with the given |download_guid|. 59 // Marks the |request| as having started with the given |download_guid|.
56 // Persistent storage needs to store the association so we can resume fetches 60 // Persistent storage needs to store the association so we can resume fetches
57 // after a browser restart, here we just verify that the |request| is active. 61 // after a browser restart, here we just verify that the |request| is active.
58 void MarkRequestAsStarted(const BackgroundFetchRequestInfo& request, 62 void MarkRequestAsStarted(BackgroundFetchRequestInfo* request,
59 const std::string& download_guid) { 63 const std::string& download_guid) {
60 const auto iter = std::find_if( 64 const auto iter = std::find_if(
61 active_requests_.begin(), active_requests_.end(), 65 active_requests_.begin(), active_requests_.end(),
62 [&request](const BackgroundFetchRequestInfo& active_request) { 66 [&request](scoped_refptr<BackgroundFetchRequestInfo> active_request) {
63 return active_request.request_index() == request.request_index(); 67 return active_request->request_index() == request->request_index();
64 }); 68 });
65 69
66 // The |request| must have been consumed from this RegistrationData. 70 // The |request| must have been consumed from this RegistrationData.
67 DCHECK(iter != active_requests_.end()); 71 DCHECK(iter != active_requests_.end());
68 } 72 }
69 73
70 // Marks the |request| as having completed. Verifies that the |request| is 74 // Marks the |request| as having completed. Verifies that the |request| is
71 // currently active and moves it to the |completed_requests_| vector. 75 // currently active and moves it to the |completed_requests_| vector.
72 void MarkRequestAsComplete(const BackgroundFetchRequestInfo& request) { 76 void MarkRequestAsComplete(BackgroundFetchRequestInfo* request) {
73 const auto iter = std::find_if( 77 const auto iter = std::find_if(
74 active_requests_.begin(), active_requests_.end(), 78 active_requests_.begin(), active_requests_.end(),
75 [&request](const BackgroundFetchRequestInfo& active_request) { 79 [&request](scoped_refptr<BackgroundFetchRequestInfo> active_request) {
76 return active_request.request_index() == request.request_index(); 80 return active_request->request_index() == request->request_index();
77 }); 81 });
78 82
79 // The |request| must have been consumed from this RegistrationData. 83 // The |request| must have been consumed from this RegistrationData.
80 DCHECK(iter != active_requests_.end()); 84 DCHECK(iter != active_requests_.end());
81 85
86 completed_requests_.push_back(*iter);
82 active_requests_.erase(iter); 87 active_requests_.erase(iter);
83 completed_requests_.push_back(request);
84 } 88 }
85 89
86 // Returns the vector with all completed requests part of this registration. 90 // Returns the vector with all completed requests part of this registration.
87 const std::vector<BackgroundFetchRequestInfo>& GetCompletedRequests() const { 91 const std::vector<scoped_refptr<BackgroundFetchRequestInfo>>&
92 GetCompletedRequests() const {
88 return completed_requests_; 93 return completed_requests_;
89 } 94 }
90 95
91 private: 96 private:
92 BackgroundFetchOptions options_; 97 BackgroundFetchOptions options_;
93 98
94 // TODO(peter): BackgroundFetchRequestInfo should be stored in a 99 std::queue<scoped_refptr<BackgroundFetchRequestInfo>> pending_requests_;
95 // unique_ptr, owned by the BackgroundFetchJobController. Right now we 100 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> active_requests_;
96 // can't do that as we need to hold on to copies here.
97 std::queue<BackgroundFetchRequestInfo> pending_requests_;
98 std::vector<BackgroundFetchRequestInfo> active_requests_;
99 101
100 // TODO(peter): Right now it's safe for this to be a vector because we only 102 // TODO(peter): Right now it's safe for this to be a vector because we only
101 // allow a single parallel request. That stops when we start allowing more. 103 // allow a single parallel request. That stops when we start allowing more.
102 static_assert(kMaximumBackgroundFetchParallelRequests == 1, 104 static_assert(kMaximumBackgroundFetchParallelRequests == 1,
103 "RegistrationData::completed_requests_ assumes no parallelism"); 105 "RegistrationData::completed_requests_ assumes no parallelism");
104 106
105 std::vector<BackgroundFetchRequestInfo> completed_requests_; 107 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> completed_requests_;
106 108
107 DISALLOW_COPY_AND_ASSIGN(RegistrationData); 109 DISALLOW_COPY_AND_ASSIGN(RegistrationData);
108 }; 110 };
109 111
110 BackgroundFetchDataManager::BackgroundFetchDataManager( 112 BackgroundFetchDataManager::BackgroundFetchDataManager(
111 BrowserContext* browser_context) 113 BrowserContext* browser_context)
112 : weak_ptr_factory_(this) { 114 : weak_ptr_factory_(this) {
113 DCHECK_CURRENTLY_ON(BrowserThread::UI); 115 DCHECK_CURRENTLY_ON(BrowserThread::UI);
114 DCHECK(browser_context); 116 DCHECK(browser_context);
115 117
116 // Store the blob storage context for the given |browser_context|. 118 // Store the blob storage context for the given |browser_context|.
117 blob_storage_context_ = 119 blob_storage_context_ =
118 make_scoped_refptr(ChromeBlobStorageContext::GetFor(browser_context)); 120 make_scoped_refptr(ChromeBlobStorageContext::GetFor(browser_context));
119 DCHECK(blob_storage_context_); 121 DCHECK(blob_storage_context_);
120 } 122 }
121 123
122 BackgroundFetchDataManager::~BackgroundFetchDataManager() = default; 124 BackgroundFetchDataManager::~BackgroundFetchDataManager() = default;
123 125
124 void BackgroundFetchDataManager::CreateRegistration( 126 void BackgroundFetchDataManager::CreateRegistration(
125 const BackgroundFetchRegistrationId& registration_id, 127 const BackgroundFetchRegistrationId& registration_id,
126 const std::vector<ServiceWorkerFetchRequest>& requests, 128 const std::vector<ServiceWorkerFetchRequest>& requests,
127 const BackgroundFetchOptions& options, 129 const BackgroundFetchOptions& options,
128 CreateRegistrationCallback callback) { 130 CreateRegistrationCallback callback) {
129 if (registrations_.find(registration_id) != registrations_.end()) { 131 if (registrations_.find(registration_id) != registrations_.end()) {
130 std::move(callback).Run(blink::mojom::BackgroundFetchError::DUPLICATED_TAG, 132 std::move(callback).Run(
131 std::vector<BackgroundFetchRequestInfo>()); 133 blink::mojom::BackgroundFetchError::DUPLICATED_TAG,
134 std::vector<scoped_refptr<BackgroundFetchRequestInfo>>());
132 return; 135 return;
133 } 136 }
134 137
135 std::unique_ptr<RegistrationData> registration_data = 138 std::unique_ptr<RegistrationData> registration_data =
136 base::MakeUnique<RegistrationData>(requests, options); 139 base::MakeUnique<RegistrationData>(requests, options);
137 140
138 // Create a vector with the initial requests to feed the Job Controller with. 141 // Create a vector with the initial requests to feed the Job Controller with.
139 std::vector<BackgroundFetchRequestInfo> initial_requests; 142 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> initial_requests;
140 for (size_t i = 0; i < kMaximumBackgroundFetchParallelRequests; ++i) { 143 for (size_t i = 0; i < kMaximumBackgroundFetchParallelRequests; ++i) {
141 if (!registration_data->HasPendingRequests()) 144 if (!registration_data->HasPendingRequests())
142 break; 145 break;
143 146
144 initial_requests.push_back(registration_data->GetPendingRequest()); 147 initial_requests.push_back(registration_data->GetPendingRequest());
145 } 148 }
146 149
147 // Store the created |registration_data| so that we can easily access it. 150 // Store the created |registration_data| so that we can easily access it.
148 registrations_.insert( 151 registrations_.insert(
149 std::make_pair(registration_id, std::move(registration_data))); 152 std::make_pair(registration_id, std::move(registration_data)));
150 153
151 // Inform the |callback| of the newly created registration. 154 // Inform the |callback| of the newly created registration.
152 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE, 155 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE,
153 std::move(initial_requests)); 156 std::move(initial_requests));
154 } 157 }
155 158
156 void BackgroundFetchDataManager::MarkRequestAsStarted( 159 void BackgroundFetchDataManager::MarkRequestAsStarted(
157 const BackgroundFetchRegistrationId& registration_id, 160 const BackgroundFetchRegistrationId& registration_id,
158 const BackgroundFetchRequestInfo& request, 161 BackgroundFetchRequestInfo* request,
159 const std::string& download_guid) { 162 const std::string& download_guid) {
160 auto iter = registrations_.find(registration_id); 163 auto iter = registrations_.find(registration_id);
161 DCHECK(iter != registrations_.end()); 164 DCHECK(iter != registrations_.end());
162 165
163 RegistrationData* registration_data = iter->second.get(); 166 RegistrationData* registration_data = iter->second.get();
164 registration_data->MarkRequestAsStarted(request, download_guid); 167 registration_data->MarkRequestAsStarted(request, download_guid);
165 } 168 }
166 169
167 void BackgroundFetchDataManager::MarkRequestAsCompleteAndGetNextRequest( 170 void BackgroundFetchDataManager::MarkRequestAsCompleteAndGetNextRequest(
168 const BackgroundFetchRegistrationId& registration_id, 171 const BackgroundFetchRegistrationId& registration_id,
169 const BackgroundFetchRequestInfo& request, 172 BackgroundFetchRequestInfo* request,
170 NextRequestCallback callback) { 173 NextRequestCallback callback) {
171 auto iter = registrations_.find(registration_id); 174 auto iter = registrations_.find(registration_id);
172 DCHECK(iter != registrations_.end()); 175 DCHECK(iter != registrations_.end());
173 176
174 RegistrationData* registration_data = iter->second.get(); 177 RegistrationData* registration_data = iter->second.get();
175 registration_data->MarkRequestAsComplete(request); 178 registration_data->MarkRequestAsComplete(request);
176 179
177 base::Optional<BackgroundFetchRequestInfo> next_request; 180 scoped_refptr<BackgroundFetchRequestInfo> next_request;
178 if (registration_data->HasPendingRequests()) 181 if (registration_data->HasPendingRequests())
179 next_request = registration_data->GetPendingRequest(); 182 next_request = registration_data->GetPendingRequest();
180 183
181 std::move(callback).Run(next_request); 184 std::move(callback).Run(std::move(next_request));
182 } 185 }
183 186
184 void BackgroundFetchDataManager::GetSettledFetchesForRegistration( 187 void BackgroundFetchDataManager::GetSettledFetchesForRegistration(
185 const BackgroundFetchRegistrationId& registration_id, 188 const BackgroundFetchRegistrationId& registration_id,
186 SettledFetchesCallback callback) { 189 SettledFetchesCallback callback) {
187 auto iter = registrations_.find(registration_id); 190 auto iter = registrations_.find(registration_id);
188 DCHECK(iter != registrations_.end()); 191 DCHECK(iter != registrations_.end());
189 192
190 RegistrationData* registration_data = iter->second.get(); 193 RegistrationData* registration_data = iter->second.get();
191 DCHECK(!registration_data->HasPendingRequests()); 194 DCHECK(!registration_data->HasPendingRequests());
192 195
193 const std::vector<BackgroundFetchRequestInfo>& requests = 196 const std::vector<scoped_refptr<BackgroundFetchRequestInfo>>& requests =
194 registration_data->GetCompletedRequests(); 197 registration_data->GetCompletedRequests();
195 198
196 std::vector<BackgroundFetchSettledFetch> settled_fetches; 199 std::vector<BackgroundFetchSettledFetch> settled_fetches;
197 settled_fetches.reserve(requests.size()); 200 settled_fetches.reserve(requests.size());
198 201
199 std::vector<std::unique_ptr<BlobHandle>> blob_handles; 202 std::vector<std::unique_ptr<BlobHandle>> blob_handles;
200 203
201 for (const auto& request : requests) { 204 for (const auto& request : requests) {
202 BackgroundFetchSettledFetch settled_fetch; 205 BackgroundFetchSettledFetch settled_fetch;
203 settled_fetch.request = request.fetch_request(); 206 settled_fetch.request = request->fetch_request();
204 207
205 settled_fetch.response.url_list.push_back(request.GetURL()); 208 settled_fetch.response.url_list.push_back(request->GetURL());
206 // TODO: settled_fetch.response.status_code 209 // TODO: settled_fetch.response.status_code
207 // TODO: settled_fetch.response.status_text 210 // TODO: settled_fetch.response.status_text
208 // TODO: settled_fetch.response.response_type 211 // TODO: settled_fetch.response.response_type
209 // TODO: settled_fetch.response.headers 212 // TODO: settled_fetch.response.headers
210 213
211 if (request.received_bytes() > 0) { 214 if (request->received_bytes() > 0) {
212 DCHECK(!request.file_path().empty()); 215 DCHECK(!request->file_path().empty());
213 216
214 std::unique_ptr<BlobHandle> blob_handle = 217 std::unique_ptr<BlobHandle> blob_handle =
215 blob_storage_context_->CreateFileBackedBlob( 218 blob_storage_context_->CreateFileBackedBlob(
216 request.file_path(), 0 /* offset */, request.received_bytes(), 219 request->file_path(), 0 /* offset */, request->received_bytes(),
217 base::Time() /* expected_modification_time */); 220 base::Time() /* expected_modification_time */);
218 221
219 // TODO(peter): Appropriately handle !blob_handle 222 // TODO(peter): Appropriately handle !blob_handle
220 if (blob_handle) { 223 if (blob_handle) {
221 settled_fetch.response.blob_uuid = blob_handle->GetUUID(); 224 settled_fetch.response.blob_uuid = blob_handle->GetUUID();
222 settled_fetch.response.blob_size = request.received_bytes(); 225 settled_fetch.response.blob_size = request->received_bytes();
223 226
224 blob_handles.push_back(std::move(blob_handle)); 227 blob_handles.push_back(std::move(blob_handle));
225 } 228 }
226 } 229 }
227 230
228 // TODO: settled_fetch.response.error 231 // TODO: settled_fetch.response.error
229 // TODO: settled_fetch.response.response_time 232 // TODO: settled_fetch.response.response_time
230 // TODO: settled_fetch.response.cors_exposed_header_names 233 // TODO: settled_fetch.response.cors_exposed_header_names
231 234
232 settled_fetches.push_back(settled_fetch); 235 settled_fetches.push_back(settled_fetch);
(...skipping 11 matching lines...) Expand all
244 std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_TAG); 247 std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_TAG);
245 return; 248 return;
246 } 249 }
247 250
248 registrations_.erase(iter); 251 registrations_.erase(iter);
249 252
250 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE); 253 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE);
251 } 254 }
252 255
253 } // namespace content 256 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698