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

Side by Side Diff: components/sync/device_info/device_info_sync_bridge.cc

Issue 2618483003: [Sync] Introduce ModelError for USS error handling. (Closed)
Patch Set: Address comments. Created 3 years, 11 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/sync/device_info/device_info_sync_bridge.h" 5 #include "components/sync/device_info/device_info_sync_bridge.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <set> 10 #include <set>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "components/sync/base/time.h" 17 #include "components/sync/base/time.h"
18 #include "components/sync/device_info/device_info_util.h" 18 #include "components/sync/device_info/device_info_util.h"
19 #include "components/sync/model/entity_change.h" 19 #include "components/sync/model/entity_change.h"
20 #include "components/sync/model/metadata_batch.h" 20 #include "components/sync/model/metadata_batch.h"
21 #include "components/sync/model/model_error.h"
21 #include "components/sync/model/mutable_data_batch.h" 22 #include "components/sync/model/mutable_data_batch.h"
22 #include "components/sync/model/sync_error.h"
23 #include "components/sync/protocol/model_type_state.pb.h" 23 #include "components/sync/protocol/model_type_state.pb.h"
24 #include "components/sync/protocol/sync.pb.h" 24 #include "components/sync/protocol/sync.pb.h"
25 25
26 namespace syncer { 26 namespace syncer {
27 27
28 using base::Time; 28 using base::Time;
29 using base::TimeDelta; 29 using base::TimeDelta;
30 using sync_pb::DeviceInfoSpecifics; 30 using sync_pb::DeviceInfoSpecifics;
31 using sync_pb::EntitySpecifics; 31 using sync_pb::EntitySpecifics;
32 using sync_pb::ModelTypeState; 32 using sync_pb::ModelTypeState;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 base::Bind(&DeviceInfoSyncBridge::OnStoreCreated, base::AsWeakPtr(this))); 106 base::Bind(&DeviceInfoSyncBridge::OnStoreCreated, base::AsWeakPtr(this)));
107 } 107 }
108 108
109 DeviceInfoSyncBridge::~DeviceInfoSyncBridge() {} 109 DeviceInfoSyncBridge::~DeviceInfoSyncBridge() {}
110 110
111 std::unique_ptr<MetadataChangeList> 111 std::unique_ptr<MetadataChangeList>
112 DeviceInfoSyncBridge::CreateMetadataChangeList() { 112 DeviceInfoSyncBridge::CreateMetadataChangeList() {
113 return WriteBatch::CreateMetadataChangeList(); 113 return WriteBatch::CreateMetadataChangeList();
114 } 114 }
115 115
116 SyncError DeviceInfoSyncBridge::MergeSyncData( 116 ModelError DeviceInfoSyncBridge::MergeSyncData(
117 std::unique_ptr<MetadataChangeList> metadata_change_list, 117 std::unique_ptr<MetadataChangeList> metadata_change_list,
118 EntityDataMap entity_data_map) { 118 EntityDataMap entity_data_map) {
119 DCHECK(has_provider_initialized_); 119 DCHECK(has_provider_initialized_);
120 DCHECK(change_processor()->IsTrackingMetadata()); 120 DCHECK(change_processor()->IsTrackingMetadata());
121 const DeviceInfo* local_info = 121 const DeviceInfo* local_info =
122 local_device_info_provider_->GetLocalDeviceInfo(); 122 local_device_info_provider_->GetLocalDeviceInfo();
123 // If our dependency was yanked out from beneath us, we cannot correctly 123 // If our dependency was yanked out from beneath us, we cannot correctly
124 // handle this request, and all our data will be deleted soon. 124 // handle this request, and all our data will be deleted soon.
125 if (local_info == nullptr) { 125 if (local_info == nullptr) {
126 return SyncError(); 126 return ModelError();
127 } 127 }
128 128
129 // Local data should typically be near empty, with the only possible value 129 // Local data should typically be near empty, with the only possible value
130 // corresponding to this device. This is because on signout all device info 130 // corresponding to this device. This is because on signout all device info
131 // data is blown away. However, this simplification is being ignored here and 131 // data is blown away. However, this simplification is being ignored here and
132 // a full difference is going to be calculated to explore what other bridge 132 // a full difference is going to be calculated to explore what other bridge
133 // implementations may look like. 133 // implementations may look like.
134 std::set<std::string> local_guids_to_put; 134 std::set<std::string> local_guids_to_put;
135 for (const auto& kv : all_data_) { 135 for (const auto& kv : all_data_) {
136 local_guids_to_put.insert(kv.first); 136 local_guids_to_put.insert(kv.first);
(...skipping 20 matching lines...) Expand all
157 } 157 }
158 } 158 }
159 159
160 for (const std::string& guid : local_guids_to_put) { 160 for (const std::string& guid : local_guids_to_put) {
161 change_processor()->Put(guid, CopyToEntityData(*all_data_[guid]), 161 change_processor()->Put(guid, CopyToEntityData(*all_data_[guid]),
162 metadata_change_list.get()); 162 metadata_change_list.get());
163 } 163 }
164 164
165 batch->TransferMetadataChanges(std::move(metadata_change_list)); 165 batch->TransferMetadataChanges(std::move(metadata_change_list));
166 CommitAndNotify(std::move(batch), has_changes); 166 CommitAndNotify(std::move(batch), has_changes);
167 return SyncError(); 167 return ModelError();
168 } 168 }
169 169
170 SyncError DeviceInfoSyncBridge::ApplySyncChanges( 170 ModelError DeviceInfoSyncBridge::ApplySyncChanges(
171 std::unique_ptr<MetadataChangeList> metadata_change_list, 171 std::unique_ptr<MetadataChangeList> metadata_change_list,
172 EntityChangeList entity_changes) { 172 EntityChangeList entity_changes) {
173 DCHECK(has_provider_initialized_); 173 DCHECK(has_provider_initialized_);
174 const DeviceInfo* local_info = 174 const DeviceInfo* local_info =
175 local_device_info_provider_->GetLocalDeviceInfo(); 175 local_device_info_provider_->GetLocalDeviceInfo();
176 // If our dependency was yanked out from beneath us, we cannot correctly 176 // If our dependency was yanked out from beneath us, we cannot correctly
177 // handle this request, and all our data will be deleted soon. 177 // handle this request, and all our data will be deleted soon.
178 if (local_info == nullptr) { 178 if (local_info == nullptr) {
179 return SyncError(); 179 return ModelError();
180 } 180 }
181 181
182 std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); 182 std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch();
183 bool has_changes = false; 183 bool has_changes = false;
184 for (EntityChange& change : entity_changes) { 184 for (EntityChange& change : entity_changes) {
185 const std::string guid = change.storage_key(); 185 const std::string guid = change.storage_key();
186 // Each device is the authoritative source for itself, ignore any remote 186 // Each device is the authoritative source for itself, ignore any remote
187 // changes that have our local cache guid. 187 // changes that have our local cache guid.
188 if (guid == local_info->guid()) { 188 if (guid == local_info->guid()) {
189 continue; 189 continue;
190 } 190 }
191 191
192 if (change.type() == EntityChange::ACTION_DELETE) { 192 if (change.type() == EntityChange::ACTION_DELETE) {
193 has_changes |= DeleteSpecifics(guid, batch.get()); 193 has_changes |= DeleteSpecifics(guid, batch.get());
194 } else { 194 } else {
195 const DeviceInfoSpecifics& specifics = 195 const DeviceInfoSpecifics& specifics =
196 change.data().specifics.device_info(); 196 change.data().specifics.device_info();
197 DCHECK(guid == specifics.cache_guid()); 197 DCHECK(guid == specifics.cache_guid());
198 StoreSpecifics(base::MakeUnique<DeviceInfoSpecifics>(specifics), 198 StoreSpecifics(base::MakeUnique<DeviceInfoSpecifics>(specifics),
199 batch.get()); 199 batch.get());
200 has_changes = true; 200 has_changes = true;
201 } 201 }
202 } 202 }
203 203
204 batch->TransferMetadataChanges(std::move(metadata_change_list)); 204 batch->TransferMetadataChanges(std::move(metadata_change_list));
205 CommitAndNotify(std::move(batch), has_changes); 205 CommitAndNotify(std::move(batch), has_changes);
206 return SyncError(); 206 return ModelError();
207 } 207 }
208 208
209 void DeviceInfoSyncBridge::GetData(StorageKeyList storage_keys, 209 void DeviceInfoSyncBridge::GetData(StorageKeyList storage_keys,
210 DataCallback callback) { 210 DataCallback callback) {
211 auto batch = base::MakeUnique<MutableDataBatch>(); 211 auto batch = base::MakeUnique<MutableDataBatch>();
212 for (const auto& key : storage_keys) { 212 for (const auto& key : storage_keys) {
213 const auto& iter = all_data_.find(key); 213 const auto& iter = all_data_.find(key);
214 if (iter != all_data_.end()) { 214 if (iter != all_data_.end()) {
215 DCHECK_EQ(key, iter->second->cache_guid()); 215 DCHECK_EQ(key, iter->second->cache_guid());
216 batch->Put(key, CopyToEntityData(*iter->second)); 216 batch->Put(key, CopyToEntityData(*iter->second));
217 } 217 }
218 } 218 }
219 callback.Run(SyncError(), std::move(batch)); 219 callback.Run(std::move(batch));
220 } 220 }
221 221
222 void DeviceInfoSyncBridge::GetAllData(DataCallback callback) { 222 void DeviceInfoSyncBridge::GetAllData(DataCallback callback) {
223 auto batch = base::MakeUnique<MutableDataBatch>(); 223 auto batch = base::MakeUnique<MutableDataBatch>();
224 for (const auto& kv : all_data_) { 224 for (const auto& kv : all_data_) {
225 batch->Put(kv.first, CopyToEntityData(*kv.second)); 225 batch->Put(kv.first, CopyToEntityData(*kv.second));
226 } 226 }
227 callback.Run(SyncError(), std::move(batch)); 227 callback.Run(std::move(batch));
228 } 228 }
229 229
230 std::string DeviceInfoSyncBridge::GetClientTag(const EntityData& entity_data) { 230 std::string DeviceInfoSyncBridge::GetClientTag(const EntityData& entity_data) {
231 DCHECK(entity_data.specifics.has_device_info()); 231 DCHECK(entity_data.specifics.has_device_info());
232 return DeviceInfoUtil::SpecificsToTag(entity_data.specifics.device_info()); 232 return DeviceInfoUtil::SpecificsToTag(entity_data.specifics.device_info());
233 } 233 }
234 234
235 std::string DeviceInfoSyncBridge::GetStorageKey(const EntityData& entity_data) { 235 std::string DeviceInfoSyncBridge::GetStorageKey(const EntityData& entity_data) {
236 DCHECK(entity_data.specifics.has_device_info()); 236 DCHECK(entity_data.specifics.has_device_info());
237 return entity_data.specifics.device_info().cache_guid(); 237 return entity_data.specifics.device_info().cache_guid();
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 } 336 }
337 337
338 void DeviceInfoSyncBridge::OnStoreCreated( 338 void DeviceInfoSyncBridge::OnStoreCreated(
339 Result result, 339 Result result,
340 std::unique_ptr<ModelTypeStore> store) { 340 std::unique_ptr<ModelTypeStore> store) {
341 if (result == Result::SUCCESS) { 341 if (result == Result::SUCCESS) {
342 std::swap(store_, store); 342 std::swap(store_, store);
343 store_->ReadAllData(base::Bind(&DeviceInfoSyncBridge::OnReadAllData, 343 store_->ReadAllData(base::Bind(&DeviceInfoSyncBridge::OnReadAllData,
344 base::AsWeakPtr(this))); 344 base::AsWeakPtr(this)));
345 } else { 345 } else {
346 ReportStartupErrorToSync("ModelTypeStore creation failed."); 346 change_processor()->ReportError(FROM_HERE,
347 "ModelTypeStore creation failed.");
347 } 348 }
348 } 349 }
349 350
350 void DeviceInfoSyncBridge::OnReadAllData( 351 void DeviceInfoSyncBridge::OnReadAllData(
351 Result result, 352 Result result,
352 std::unique_ptr<RecordList> record_list) { 353 std::unique_ptr<RecordList> record_list) {
353 if (result != Result::SUCCESS) { 354 if (result != Result::SUCCESS) {
354 ReportStartupErrorToSync("Initial load of data failed."); 355 change_processor()->ReportError(FROM_HERE, "Initial load of data failed.");
355 return; 356 return;
356 } 357 }
357 358
358 for (const Record& r : *record_list.get()) { 359 for (const Record& r : *record_list.get()) {
359 std::unique_ptr<DeviceInfoSpecifics> specifics = 360 std::unique_ptr<DeviceInfoSpecifics> specifics =
360 base::MakeUnique<DeviceInfoSpecifics>(); 361 base::MakeUnique<DeviceInfoSpecifics>();
361 if (specifics->ParseFromString(r.value)) { 362 if (specifics->ParseFromString(r.value)) {
362 all_data_[specifics->cache_guid()] = std::move(specifics); 363 all_data_[specifics->cache_guid()] = std::move(specifics);
363 } else { 364 } else {
364 ReportStartupErrorToSync("Failed to deserialize specifics."); 365 change_processor()->ReportError(FROM_HERE,
366 "Failed to deserialize specifics.");
367 return;
365 } 368 }
366 } 369 }
367 370
368 has_data_loaded_ = true; 371 has_data_loaded_ = true;
369 LoadMetadataIfReady(); 372 LoadMetadataIfReady();
370 } 373 }
371 374
372 void DeviceInfoSyncBridge::LoadMetadataIfReady() { 375 void DeviceInfoSyncBridge::LoadMetadataIfReady() {
373 if (has_data_loaded_ && has_provider_initialized_) { 376 if (has_data_loaded_ && has_provider_initialized_) {
374 store_->ReadAllMetadata(base::Bind(&DeviceInfoSyncBridge::OnReadAllMetadata, 377 store_->ReadAllMetadata(base::Bind(&DeviceInfoSyncBridge::OnReadAllMetadata,
375 base::AsWeakPtr(this))); 378 base::AsWeakPtr(this)));
376 } 379 }
377 } 380 }
378 381
379 void DeviceInfoSyncBridge::OnReadAllMetadata( 382 void DeviceInfoSyncBridge::OnReadAllMetadata(
380 SyncError error, 383 ModelError error,
381 std::unique_ptr<MetadataBatch> metadata_batch) { 384 std::unique_ptr<MetadataBatch> metadata_batch) {
382 change_processor()->OnMetadataLoaded(error, std::move(metadata_batch)); 385 if (error.IsSet()) {
386 change_processor()->ReportError(error);
387 return;
388 }
389
390 change_processor()->OnMetadataLoaded(std::move(metadata_batch));
383 ReconcileLocalAndStored(); 391 ReconcileLocalAndStored();
384 } 392 }
385 393
386 void DeviceInfoSyncBridge::OnCommit(Result result) { 394 void DeviceInfoSyncBridge::OnCommit(Result result) {
387 if (result != Result::SUCCESS) { 395 if (result != Result::SUCCESS) {
388 change_processor()->CreateAndUploadError(FROM_HERE, 396 change_processor()->ReportError(FROM_HERE, "Failed a write to store.");
389 "Failed a write to store.");
390 } 397 }
391 } 398 }
392 399
393 void DeviceInfoSyncBridge::ReconcileLocalAndStored() { 400 void DeviceInfoSyncBridge::ReconcileLocalAndStored() {
394 // On initial syncing we will have a change processor here, but it will not be 401 // On initial syncing we will have a change processor here, but it will not be
395 // tracking changes. We need to persist a copy of our local device info to 402 // tracking changes. We need to persist a copy of our local device info to
396 // disk, but the Put call to the processor will be ignored. That should be 403 // disk, but the Put call to the processor will be ignored. That should be
397 // fine however, as the discrepancy will be picked up later in merge. We don't 404 // fine however, as the discrepancy will be picked up later in merge. We don't
398 // bother trying to track this case and act intelligently because simply not 405 // bother trying to track this case and act intelligently because simply not
399 // much of a benefit in doing so. 406 // much of a benefit in doing so.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 } 472 }
466 473
467 int DeviceInfoSyncBridge::CountActiveDevices(const Time now) const { 474 int DeviceInfoSyncBridge::CountActiveDevices(const Time now) const {
468 return std::count_if(all_data_.begin(), all_data_.end(), 475 return std::count_if(all_data_.begin(), all_data_.end(),
469 [now](ClientIdToSpecifics::const_reference pair) { 476 [now](ClientIdToSpecifics::const_reference pair) {
470 return DeviceInfoUtil::IsActive( 477 return DeviceInfoUtil::IsActive(
471 GetLastUpdateTime(*pair.second), now); 478 GetLastUpdateTime(*pair.second), now);
472 }); 479 });
473 } 480 }
474 481
475 void DeviceInfoSyncBridge::ReportStartupErrorToSync(const std::string& msg) {
476 // TODO(skym): Shouldn't need to log this here, reporting should always log.
477 LOG(WARNING) << msg;
478 change_processor()->OnMetadataLoaded(
479 change_processor()->CreateAndUploadError(FROM_HERE, msg), nullptr);
480 }
481
482 } // namespace syncer 482 } // namespace syncer
OLDNEW
« no previous file with comments | « components/sync/device_info/device_info_sync_bridge.h ('k') | components/sync/device_info/device_info_sync_bridge_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698