Chromium Code Reviews| 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 | |
| 7 #include "base/bind.h" | 9 #include "base/bind.h" |
| 8 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 9 #include "base/thread_task_runner_handle.h" | 11 #include "base/thread_task_runner_handle.h" |
| 10 #include "sync/api/attachments/attachment.h" | 12 #include "sync/api/attachments/attachment.h" |
| 11 #include "sync/api/attachments/fake_attachment_store.h" | 13 #include "sync/api/attachments/fake_attachment_store.h" |
| 12 #include "sync/internal_api/public/attachments/fake_attachment_downloader.h" | 14 #include "sync/internal_api/public/attachments/fake_attachment_downloader.h" |
| 13 #include "sync/internal_api/public/attachments/fake_attachment_uploader.h" | 15 #include "sync/internal_api/public/attachments/fake_attachment_uploader.h" |
| 14 | 16 |
| 15 namespace syncer { | 17 namespace syncer { |
| 16 | 18 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 scoped_ptr<AttachmentDownloader> attachment_downloader( | 136 scoped_ptr<AttachmentDownloader> attachment_downloader( |
| 135 new FakeAttachmentDownloader()); | 137 new FakeAttachmentDownloader()); |
| 136 scoped_ptr<syncer::AttachmentService> attachment_service( | 138 scoped_ptr<syncer::AttachmentService> attachment_service( |
| 137 new syncer::AttachmentServiceImpl(attachment_store.Pass(), | 139 new syncer::AttachmentServiceImpl(attachment_store.Pass(), |
| 138 attachment_uploader.Pass(), | 140 attachment_uploader.Pass(), |
| 139 attachment_downloader.Pass(), | 141 attachment_downloader.Pass(), |
| 140 NULL)); | 142 NULL)); |
| 141 return attachment_service.Pass(); | 143 return attachment_service.Pass(); |
| 142 } | 144 } |
| 143 | 145 |
| 146 AttachmentStore* AttachmentServiceImpl::GetStore() { | |
| 147 return attachment_store_.get(); | |
| 148 } | |
| 149 | |
| 144 void AttachmentServiceImpl::GetOrDownloadAttachments( | 150 void AttachmentServiceImpl::GetOrDownloadAttachments( |
| 145 const AttachmentIdList& attachment_ids, | 151 const AttachmentIdList& attachment_ids, |
| 146 const GetOrDownloadCallback& callback) { | 152 const GetOrDownloadCallback& callback) { |
| 147 DCHECK(CalledOnValidThread()); | 153 DCHECK(CalledOnValidThread()); |
| 148 scoped_refptr<GetOrDownloadState> state( | 154 scoped_refptr<GetOrDownloadState> state( |
| 149 new GetOrDownloadState(attachment_ids, callback)); | 155 new GetOrDownloadState(attachment_ids, callback)); |
| 150 attachment_store_->Read(attachment_ids, | 156 attachment_store_->Read(attachment_ids, |
| 151 base::Bind(&AttachmentServiceImpl::ReadDone, | 157 base::Bind(&AttachmentServiceImpl::ReadDone, |
| 152 weak_ptr_factory_.GetWeakPtr(), | 158 weak_ptr_factory_.GetWeakPtr(), |
| 153 state)); | 159 state)); |
| 154 } | 160 } |
| 155 | 161 |
| 156 void AttachmentServiceImpl::DropAttachments( | 162 void AttachmentServiceImpl::DropAttachments( |
| 157 const AttachmentIdList& attachment_ids, | 163 const AttachmentIdList& attachment_ids, |
| 158 const DropCallback& callback) { | 164 const DropCallback& callback) { |
| 159 DCHECK(CalledOnValidThread()); | 165 DCHECK(CalledOnValidThread()); |
| 160 attachment_store_->Drop(attachment_ids, | 166 attachment_store_->Drop(attachment_ids, |
| 161 base::Bind(&AttachmentServiceImpl::DropDone, | 167 base::Bind(&AttachmentServiceImpl::DropDone, |
| 162 weak_ptr_factory_.GetWeakPtr(), | 168 weak_ptr_factory_.GetWeakPtr(), |
| 163 callback)); | 169 callback)); |
| 164 } | 170 } |
| 165 | 171 |
| 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 | |
| 185 void AttachmentServiceImpl::ReadDone( | 172 void AttachmentServiceImpl::ReadDone( |
| 186 const scoped_refptr<GetOrDownloadState>& state, | 173 const scoped_refptr<GetOrDownloadState>& state, |
| 187 const AttachmentStore::Result& result, | 174 const AttachmentStore::Result& result, |
| 188 scoped_ptr<AttachmentMap> attachments, | 175 scoped_ptr<AttachmentMap> attachments, |
| 189 scoped_ptr<AttachmentIdList> unavailable_attachment_ids) { | 176 scoped_ptr<AttachmentIdList> unavailable_attachment_ids) { |
| 190 // Add read attachments to result. | 177 // Add read attachments to result. |
| 191 for (AttachmentMap::const_iterator iter = attachments->begin(); | 178 for (AttachmentMap::const_iterator iter = attachments->begin(); |
| 192 iter != attachments->end(); | 179 iter != attachments->end(); |
| 193 ++iter) { | 180 ++iter) { |
| 194 state->AddAttachment(iter->second); | 181 state->AddAttachment(iter->second); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 219 AttachmentService::DropResult drop_result = | 206 AttachmentService::DropResult drop_result = |
| 220 AttachmentService::DROP_UNSPECIFIED_ERROR; | 207 AttachmentService::DROP_UNSPECIFIED_ERROR; |
| 221 if (result == AttachmentStore::SUCCESS) { | 208 if (result == AttachmentStore::SUCCESS) { |
| 222 drop_result = AttachmentService::DROP_SUCCESS; | 209 drop_result = AttachmentService::DROP_SUCCESS; |
| 223 } | 210 } |
| 224 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). | 211 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). |
| 225 base::MessageLoop::current()->PostTask(FROM_HERE, | 212 base::MessageLoop::current()->PostTask(FROM_HERE, |
| 226 base::Bind(callback, drop_result)); | 213 base::Bind(callback, drop_result)); |
| 227 } | 214 } |
| 228 | 215 |
| 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 | |
| 241 void AttachmentServiceImpl::UploadDone( | 216 void AttachmentServiceImpl::UploadDone( |
| 242 const AttachmentUploader::UploadResult& result, | 217 const AttachmentUploader::UploadResult& result, |
| 243 const AttachmentId& attachment_id) { | 218 const AttachmentId& attachment_id) { |
| 244 // TODO(pavely): crbug/372622: Deal with UploadAttachment failures. | 219 // TODO(pavely): crbug/372622: Deal with UploadAttachment failures. |
| 245 if (result != AttachmentUploader::UPLOAD_SUCCESS) | 220 if (result != AttachmentUploader::UPLOAD_SUCCESS) |
| 246 return; | 221 return; |
| 247 if (delegate_) { | 222 if (delegate_) { |
| 248 delegate_->OnAttachmentUploaded(attachment_id); | 223 delegate_->OnAttachmentUploaded(attachment_id); |
| 249 } | 224 } |
| 250 } | 225 } |
| 251 | 226 |
| 252 void AttachmentServiceImpl::DownloadDone( | 227 void AttachmentServiceImpl::DownloadDone( |
| 253 const scoped_refptr<GetOrDownloadState>& state, | 228 const scoped_refptr<GetOrDownloadState>& state, |
| 254 const AttachmentId& attachment_id, | 229 const AttachmentId& attachment_id, |
| 255 const AttachmentDownloader::DownloadResult& result, | 230 const AttachmentDownloader::DownloadResult& result, |
| 256 scoped_ptr<Attachment> attachment) { | 231 scoped_ptr<Attachment> attachment) { |
| 257 if (result == AttachmentDownloader::DOWNLOAD_SUCCESS) { | 232 if (result == AttachmentDownloader::DOWNLOAD_SUCCESS) { |
| 258 state->AddAttachment(*attachment.get()); | 233 state->AddAttachment(*attachment.get()); |
| 259 } else { | 234 } else { |
| 260 state->AddUnavailableAttachmentId(attachment_id); | 235 state->AddUnavailableAttachmentId(attachment_id); |
| 261 } | 236 } |
| 262 } | 237 } |
| 263 | 238 |
| 239 void AttachmentServiceImpl::UploadAttachments( | |
| 240 const AttachmentIdSet& attachment_ids) { | |
| 241 DCHECK(CalledOnValidThread()); | |
| 242 if (!attachment_uploader_.get()) { | |
| 243 return; | |
| 244 } | |
| 245 | |
| 246 // Enqueue the attachment ids that aren't already in the queue. | |
| 247 AttachmentIdSet::const_iterator iter = attachment_ids.begin(); | |
| 248 AttachmentIdSet::const_iterator end = attachment_ids.end(); | |
| 249 for (; iter != end; ++iter) { | |
| 250 if (ids_in_queue_.find(*iter) == ids_in_queue_.end()) { | |
| 251 queue_.push_back(*iter); | |
| 252 ids_in_queue_.insert(*iter); | |
| 253 } | |
| 254 } | |
| 255 | |
| 256 ProcessQueuedUploads(); | |
| 257 } | |
| 258 | |
| 259 void AttachmentServiceImpl::ProcessQueuedUploads() { | |
| 260 DCHECK(CalledOnValidThread()); | |
| 261 // TODO(maniscalco): Don't dequeue them all. Instead, limit the number of | |
| 262 // concurrent uploads and apply backoff on failure. | |
| 263 while (!queue_.empty()) { | |
| 264 const AttachmentId id = queue_.front(); | |
| 265 queue_.pop_front(); | |
| 266 ids_in_queue_.erase(id); | |
|
pavely
2014/09/04 17:44:37
This should go into UploadDone. We discussed that.
maniscalco
2014/09/04 22:39:38
Good catch. Done. I also updated the data member
| |
| 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 | |
| 264 } // namespace syncer | 296 } // namespace syncer |
| OLD | NEW |