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

Side by Side Diff: sync/engine/verify_updates_command.cc

Issue 9702083: sync: Count and report reflected updates (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update python test server Created 8 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/engine/verify_updates_command.h" 5 #include "sync/engine/verify_updates_command.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "sync/engine/syncer.h" 10 #include "sync/engine/syncer.h"
11 #include "sync/engine/syncer_proto_util.h" 11 #include "sync/engine/syncer_proto_util.h"
12 #include "sync/engine/syncer_types.h" 12 #include "sync/engine/syncer_types.h"
13 #include "sync/engine/syncer_util.h" 13 #include "sync/engine/syncer_util.h"
14 #include "sync/engine/syncproto.h" 14 #include "sync/engine/syncproto.h"
15 #include "sync/protocol/bookmark_specifics.pb.h" 15 #include "sync/protocol/bookmark_specifics.pb.h"
16 #include "sync/syncable/syncable.h" 16 #include "sync/syncable/syncable.h"
17 17
18 namespace browser_sync { 18 namespace browser_sync {
19 19
20 using syncable::WriteTransaction; 20 using syncable::WriteTransaction;
21 21
22 using syncable::GET_BY_ID; 22 using syncable::GET_BY_ID;
23 using syncable::SYNCER; 23 using syncable::SYNCER;
24 24
25 namespace {
26
27 // This function attempts to determine whether or not this update is genuinely
28 // new, or if it is a reflection of one of our own commits.
29 //
30 // There is a known inaccuracy in its implementation. If this update ends up
31 // being applied to a local item with a different ID, we will count the change
32 // as being a non-reflection update. Fortunately, the server usually updates
33 // our IDs correctly in its commit response, so a new ID during GetUpdate should
34 // be rare.
35 //
36 // The only secnarios I can think of where this might happen are:
37 // - We commit a new item to the server, but we don't persist the
38 // server-returned new ID to the database before we shut down. On the GetUpdate
39 // following the next restart, we will receive an update from the server that
40 // updates its local ID.
41 // - When two attempts to create an item with identical UNIQUE_CLIENT_TAG values
42 // collide at the server. I have seen this in testing. When it happens, the
43 // test server will send one of the clients a response to upate its local ID so
44 // that both clients will refer to the item using the same ID going forward. In
45 // this case, we're right to assume that the update is not a reflection.
46 //
47 // For more information, see SyncerUtil::FindLocalIdToUpdate().
48 bool UpdateContainsNewVersion(syncable::BaseTransaction *trans,
49 const SyncEntity &update) {
50 int64 existing_version = -1; // The server always sends positive versions.
51 syncable::Entry existing_entry(trans, GET_BY_ID, update.id());
52 if (existing_entry.good())
53 existing_version = existing_entry.Get(syncable::BASE_VERSION);
54
55 return existing_version < update.version();
56 }
57
58 // In the event that IDs match, but tags differ AttemptReuniteClient tag
59 // will have refused to unify the update.
60 // We should not attempt to apply it at all since it violates consistency
61 // rules.
62 VerifyResult VerifyTagConsistency(const SyncEntity& entry,
63 const syncable::MutableEntry& same_id) {
64 if (entry.has_client_defined_unique_tag() &&
65 entry.client_defined_unique_tag() !=
66 same_id.Get(syncable::UNIQUE_CLIENT_TAG)) {
67 return VERIFY_FAIL;
68 }
69 return VERIFY_UNDECIDED;
70 }
71 } // namespace
72
25 VerifyUpdatesCommand::VerifyUpdatesCommand() {} 73 VerifyUpdatesCommand::VerifyUpdatesCommand() {}
26 VerifyUpdatesCommand::~VerifyUpdatesCommand() {} 74 VerifyUpdatesCommand::~VerifyUpdatesCommand() {}
27 75
28 std::set<ModelSafeGroup> VerifyUpdatesCommand::GetGroupsToChange( 76 std::set<ModelSafeGroup> VerifyUpdatesCommand::GetGroupsToChange(
29 const sessions::SyncSession& session) const { 77 const sessions::SyncSession& session) const {
30 std::set<ModelSafeGroup> groups_with_updates; 78 std::set<ModelSafeGroup> groups_with_updates;
31 79
32 const GetUpdatesResponse& updates = 80 const GetUpdatesResponse& updates =
33 session.status_controller().updates_response().get_updates(); 81 session.status_controller().updates_response().get_updates();
34 for (int i = 0; i < updates.entries().size(); i++) { 82 for (int i = 0; i < updates.entries().size(); i++) {
(...skipping 20 matching lines...) Expand all
55 *reinterpret_cast<const SyncEntity *>(&(updates.entries(i))); 103 *reinterpret_cast<const SyncEntity *>(&(updates.entries(i)));
56 ModelSafeGroup g = GetGroupForModelType(update.GetModelType(), 104 ModelSafeGroup g = GetGroupForModelType(update.GetModelType(),
57 session->routing_info()); 105 session->routing_info());
58 if (g != status->group_restriction()) 106 if (g != status->group_restriction())
59 continue; 107 continue;
60 108
61 VerifyUpdateResult result = VerifyUpdate(&trans, update, 109 VerifyUpdateResult result = VerifyUpdate(&trans, update,
62 session->routing_info()); 110 session->routing_info());
63 status->mutable_update_progress()->AddVerifyResult(result.value, update); 111 status->mutable_update_progress()->AddVerifyResult(result.value, update);
64 status->increment_num_updates_downloaded_by(1); 112 status->increment_num_updates_downloaded_by(1);
113 if (!UpdateContainsNewVersion(&trans, update))
114 status->increment_num_reflected_updates_downloaded_by(1);
65 if (update.deleted()) 115 if (update.deleted())
66 status->increment_num_tombstone_updates_downloaded_by(1); 116 status->increment_num_tombstone_updates_downloaded_by(1);
67 } 117 }
68 118
69 return SYNCER_OK; 119 return SYNCER_OK;
70 } 120 }
71 121
72 namespace {
73 // In the event that IDs match, but tags differ AttemptReuniteClient tag
74 // will have refused to unify the update.
75 // We should not attempt to apply it at all since it violates consistency
76 // rules.
77 VerifyResult VerifyTagConsistency(const SyncEntity& entry,
78 const syncable::MutableEntry& same_id) {
79 if (entry.has_client_defined_unique_tag() &&
80 entry.client_defined_unique_tag() !=
81 same_id.Get(syncable::UNIQUE_CLIENT_TAG)) {
82 return VERIFY_FAIL;
83 }
84 return VERIFY_UNDECIDED;
85 }
86 } // namespace
87
88 VerifyUpdatesCommand::VerifyUpdateResult VerifyUpdatesCommand::VerifyUpdate( 122 VerifyUpdatesCommand::VerifyUpdateResult VerifyUpdatesCommand::VerifyUpdate(
89 syncable::WriteTransaction* trans, const SyncEntity& entry, 123 syncable::WriteTransaction* trans, const SyncEntity& entry,
90 const ModelSafeRoutingInfo& routes) { 124 const ModelSafeRoutingInfo& routes) {
91 syncable::Id id = entry.id(); 125 syncable::Id id = entry.id();
92 VerifyUpdateResult result = {VERIFY_FAIL, GROUP_PASSIVE}; 126 VerifyUpdateResult result = {VERIFY_FAIL, GROUP_PASSIVE};
93 127
94 const bool deleted = entry.has_deleted() && entry.deleted(); 128 const bool deleted = entry.has_deleted() && entry.deleted();
95 const bool is_directory = entry.IsFolder(); 129 const bool is_directory = entry.IsFolder();
96 const syncable::ModelType model_type = entry.GetModelType(); 130 const syncable::ModelType model_type = entry.GetModelType();
97 131
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 deleted, is_directory, model_type); 164 deleted, is_directory, model_type);
131 } 165 }
132 166
133 if (VERIFY_UNDECIDED == result.value) 167 if (VERIFY_UNDECIDED == result.value)
134 result.value = VERIFY_SUCCESS; // No news is good news. 168 result.value = VERIFY_SUCCESS; // No news is good news.
135 169
136 return result; // This might be VERIFY_SUCCESS as well 170 return result; // This might be VERIFY_SUCCESS as well
137 } 171 }
138 172
139 } // namespace browser_sync 173 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698