OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "sync/internal_api/public/attachments/attachment_service_impl.h" | 5 #include "sync/internal_api/public/attachments/attachment_service_impl.h" |
6 | 6 |
7 #include <iterator> | |
8 | |
9 #include "base/bind.h" | 7 #include "base/bind.h" |
10 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
11 #include "base/thread_task_runner_handle.h" | 9 #include "base/thread_task_runner_handle.h" |
12 #include "sync/api/attachments/attachment.h" | 10 #include "sync/api/attachments/attachment.h" |
13 #include "sync/api/attachments/fake_attachment_store.h" | 11 #include "sync/api/attachments/fake_attachment_store.h" |
14 #include "sync/internal_api/public/attachments/fake_attachment_downloader.h" | 12 #include "sync/internal_api/public/attachments/fake_attachment_downloader.h" |
15 #include "sync/internal_api/public/attachments/fake_attachment_uploader.h" | 13 #include "sync/internal_api/public/attachments/fake_attachment_uploader.h" |
16 | 14 |
17 namespace syncer { | 15 namespace syncer { |
18 | 16 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 scoped_ptr<AttachmentDownloader> attachment_downloader( | 134 scoped_ptr<AttachmentDownloader> attachment_downloader( |
137 new FakeAttachmentDownloader()); | 135 new FakeAttachmentDownloader()); |
138 scoped_ptr<syncer::AttachmentService> attachment_service( | 136 scoped_ptr<syncer::AttachmentService> attachment_service( |
139 new syncer::AttachmentServiceImpl(attachment_store.Pass(), | 137 new syncer::AttachmentServiceImpl(attachment_store.Pass(), |
140 attachment_uploader.Pass(), | 138 attachment_uploader.Pass(), |
141 attachment_downloader.Pass(), | 139 attachment_downloader.Pass(), |
142 NULL)); | 140 NULL)); |
143 return attachment_service.Pass(); | 141 return attachment_service.Pass(); |
144 } | 142 } |
145 | 143 |
146 AttachmentStore* AttachmentServiceImpl::GetStore() { | |
147 return attachment_store_.get(); | |
148 } | |
149 | |
150 void AttachmentServiceImpl::GetOrDownloadAttachments( | 144 void AttachmentServiceImpl::GetOrDownloadAttachments( |
151 const AttachmentIdList& attachment_ids, | 145 const AttachmentIdList& attachment_ids, |
152 const GetOrDownloadCallback& callback) { | 146 const GetOrDownloadCallback& callback) { |
153 DCHECK(CalledOnValidThread()); | 147 DCHECK(CalledOnValidThread()); |
154 scoped_refptr<GetOrDownloadState> state( | 148 scoped_refptr<GetOrDownloadState> state( |
155 new GetOrDownloadState(attachment_ids, callback)); | 149 new GetOrDownloadState(attachment_ids, callback)); |
156 attachment_store_->Read(attachment_ids, | 150 attachment_store_->Read(attachment_ids, |
157 base::Bind(&AttachmentServiceImpl::ReadDone, | 151 base::Bind(&AttachmentServiceImpl::ReadDone, |
158 weak_ptr_factory_.GetWeakPtr(), | 152 weak_ptr_factory_.GetWeakPtr(), |
159 state)); | 153 state)); |
160 } | 154 } |
161 | 155 |
162 void AttachmentServiceImpl::DropAttachments( | 156 void AttachmentServiceImpl::DropAttachments( |
163 const AttachmentIdList& attachment_ids, | 157 const AttachmentIdList& attachment_ids, |
164 const DropCallback& callback) { | 158 const DropCallback& callback) { |
165 DCHECK(CalledOnValidThread()); | 159 DCHECK(CalledOnValidThread()); |
166 attachment_store_->Drop(attachment_ids, | 160 attachment_store_->Drop(attachment_ids, |
167 base::Bind(&AttachmentServiceImpl::DropDone, | 161 base::Bind(&AttachmentServiceImpl::DropDone, |
168 weak_ptr_factory_.GetWeakPtr(), | 162 weak_ptr_factory_.GetWeakPtr(), |
169 callback)); | 163 callback)); |
170 } | 164 } |
171 | 165 |
| 166 void AttachmentServiceImpl::StoreAttachments(const AttachmentList& attachments, |
| 167 const StoreCallback& callback) { |
| 168 DCHECK(CalledOnValidThread()); |
| 169 attachment_store_->Write(attachments, |
| 170 base::Bind(&AttachmentServiceImpl::WriteDone, |
| 171 weak_ptr_factory_.GetWeakPtr(), |
| 172 callback)); |
| 173 if (attachment_uploader_.get()) { |
| 174 for (AttachmentList::const_iterator iter = attachments.begin(); |
| 175 iter != attachments.end(); |
| 176 ++iter) { |
| 177 attachment_uploader_->UploadAttachment( |
| 178 *iter, |
| 179 base::Bind(&AttachmentServiceImpl::UploadDone, |
| 180 weak_ptr_factory_.GetWeakPtr())); |
| 181 } |
| 182 } |
| 183 } |
| 184 |
172 void AttachmentServiceImpl::ReadDone( | 185 void AttachmentServiceImpl::ReadDone( |
173 const scoped_refptr<GetOrDownloadState>& state, | 186 const scoped_refptr<GetOrDownloadState>& state, |
174 const AttachmentStore::Result& result, | 187 const AttachmentStore::Result& result, |
175 scoped_ptr<AttachmentMap> attachments, | 188 scoped_ptr<AttachmentMap> attachments, |
176 scoped_ptr<AttachmentIdList> unavailable_attachment_ids) { | 189 scoped_ptr<AttachmentIdList> unavailable_attachment_ids) { |
177 // Add read attachments to result. | 190 // Add read attachments to result. |
178 for (AttachmentMap::const_iterator iter = attachments->begin(); | 191 for (AttachmentMap::const_iterator iter = attachments->begin(); |
179 iter != attachments->end(); | 192 iter != attachments->end(); |
180 ++iter) { | 193 ++iter) { |
181 state->AddAttachment(iter->second); | 194 state->AddAttachment(iter->second); |
(...skipping 24 matching lines...) Expand all Loading... |
206 AttachmentService::DropResult drop_result = | 219 AttachmentService::DropResult drop_result = |
207 AttachmentService::DROP_UNSPECIFIED_ERROR; | 220 AttachmentService::DROP_UNSPECIFIED_ERROR; |
208 if (result == AttachmentStore::SUCCESS) { | 221 if (result == AttachmentStore::SUCCESS) { |
209 drop_result = AttachmentService::DROP_SUCCESS; | 222 drop_result = AttachmentService::DROP_SUCCESS; |
210 } | 223 } |
211 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). | 224 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). |
212 base::MessageLoop::current()->PostTask(FROM_HERE, | 225 base::MessageLoop::current()->PostTask(FROM_HERE, |
213 base::Bind(callback, drop_result)); | 226 base::Bind(callback, drop_result)); |
214 } | 227 } |
215 | 228 |
| 229 void AttachmentServiceImpl::WriteDone(const StoreCallback& callback, |
| 230 const AttachmentStore::Result& result) { |
| 231 AttachmentService::StoreResult store_result = |
| 232 AttachmentService::STORE_UNSPECIFIED_ERROR; |
| 233 if (result == AttachmentStore::SUCCESS) { |
| 234 store_result = AttachmentService::STORE_SUCCESS; |
| 235 } |
| 236 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). |
| 237 base::MessageLoop::current()->PostTask(FROM_HERE, |
| 238 base::Bind(callback, store_result)); |
| 239 } |
| 240 |
216 void AttachmentServiceImpl::UploadDone( | 241 void AttachmentServiceImpl::UploadDone( |
217 const AttachmentUploader::UploadResult& result, | 242 const AttachmentUploader::UploadResult& result, |
218 const AttachmentId& attachment_id) { | 243 const AttachmentId& attachment_id) { |
219 ids_in_queue_.erase(attachment_id); | |
220 // TODO(pavely): crbug/372622: Deal with UploadAttachment failures. | 244 // TODO(pavely): crbug/372622: Deal with UploadAttachment failures. |
221 if (result != AttachmentUploader::UPLOAD_SUCCESS) | 245 if (result != AttachmentUploader::UPLOAD_SUCCESS) |
222 return; | 246 return; |
223 if (delegate_) { | 247 if (delegate_) { |
224 delegate_->OnAttachmentUploaded(attachment_id); | 248 delegate_->OnAttachmentUploaded(attachment_id); |
225 } | 249 } |
226 } | 250 } |
227 | 251 |
228 void AttachmentServiceImpl::DownloadDone( | 252 void AttachmentServiceImpl::DownloadDone( |
229 const scoped_refptr<GetOrDownloadState>& state, | 253 const scoped_refptr<GetOrDownloadState>& state, |
230 const AttachmentId& attachment_id, | 254 const AttachmentId& attachment_id, |
231 const AttachmentDownloader::DownloadResult& result, | 255 const AttachmentDownloader::DownloadResult& result, |
232 scoped_ptr<Attachment> attachment) { | 256 scoped_ptr<Attachment> attachment) { |
233 if (result == AttachmentDownloader::DOWNLOAD_SUCCESS) { | 257 if (result == AttachmentDownloader::DOWNLOAD_SUCCESS) { |
234 state->AddAttachment(*attachment.get()); | 258 state->AddAttachment(*attachment.get()); |
235 } else { | 259 } else { |
236 state->AddUnavailableAttachmentId(attachment_id); | 260 state->AddUnavailableAttachmentId(attachment_id); |
237 } | 261 } |
238 } | 262 } |
239 | 263 |
240 void AttachmentServiceImpl::UploadAttachments( | |
241 const AttachmentIdSet& attachment_ids) { | |
242 DCHECK(CalledOnValidThread()); | |
243 if (!attachment_uploader_.get()) { | |
244 return; | |
245 } | |
246 | |
247 // Enqueue the attachment ids that aren't already in the queue. | |
248 AttachmentIdSet::const_iterator iter = attachment_ids.begin(); | |
249 AttachmentIdSet::const_iterator end = attachment_ids.end(); | |
250 for (; iter != end; ++iter) { | |
251 if (ids_in_queue_.find(*iter) == ids_in_queue_.end()) { | |
252 queue_.push_back(*iter); | |
253 ids_in_queue_.insert(*iter); | |
254 } | |
255 } | |
256 | |
257 ProcessQueuedUploads(); | |
258 } | |
259 | |
260 void AttachmentServiceImpl::ProcessQueuedUploads() { | |
261 DCHECK(CalledOnValidThread()); | |
262 // TODO(maniscalco): Don't dequeue them all. Instead, limit the number of | |
263 // concurrent uploads and apply backoff on failure. | |
264 while (!queue_.empty()) { | |
265 const AttachmentId id = queue_.front(); | |
266 queue_.pop_front(); | |
267 AttachmentIdList attachment_ids; | |
268 attachment_ids.push_back(id); | |
269 attachment_store_->Read( | |
270 attachment_ids, | |
271 base::Bind(&AttachmentServiceImpl::ReadDoneNowUpload, | |
272 weak_ptr_factory_.GetWeakPtr())); | |
273 } | |
274 } | |
275 | |
276 void AttachmentServiceImpl::ReadDoneNowUpload( | |
277 const AttachmentStore::Result& result, | |
278 scoped_ptr<AttachmentMap> attachments, | |
279 scoped_ptr<AttachmentIdList> unavailable_attachment_ids) { | |
280 DCHECK(CalledOnValidThread()); | |
281 if (!unavailable_attachment_ids->empty()) { | |
282 // TODO(maniscalco): We failed to read some attachments. What should we do | |
283 // now? | |
284 } | |
285 | |
286 AttachmentMap::const_iterator iter = attachments->begin(); | |
287 AttachmentMap::const_iterator end = attachments->end(); | |
288 for (; iter != end; ++iter) { | |
289 attachment_uploader_->UploadAttachment( | |
290 iter->second, | |
291 base::Bind(&AttachmentServiceImpl::UploadDone, | |
292 weak_ptr_factory_.GetWeakPtr())); | |
293 } | |
294 } | |
295 | |
296 } // namespace syncer | 264 } // namespace syncer |
OLD | NEW |