OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/commit_util.h" | 5 #include "components/sync/engine_impl/commit_util.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <limits> | 9 #include <limits> |
10 #include <set> | 10 #include <set> |
11 #include <string> | 11 #include <string> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/debug/dump_without_crashing.h" | 14 #include "base/debug/dump_without_crashing.h" |
15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
16 #include "sync/engine/syncer_proto_util.h" | 16 #include "components/sync/base/attachment_id_proto.h" |
17 #include "sync/internal_api/public/base/attachment_id_proto.h" | 17 #include "components/sync/base/time.h" |
18 #include "sync/internal_api/public/base/unique_position.h" | 18 #include "components/sync/base/unique_position.h" |
19 #include "sync/protocol/bookmark_specifics.pb.h" | 19 #include "components/sync/engine_impl/syncer_proto_util.h" |
20 #include "sync/protocol/sync.pb.h" | 20 #include "components/sync/protocol/bookmark_specifics.pb.h" |
21 #include "sync/sessions/sync_session.h" | 21 #include "components/sync/protocol/sync.pb.h" |
22 #include "sync/syncable/directory.h" | 22 #include "components/sync/sessions_impl/sync_session.h" |
23 #include "sync/syncable/entry.h" | 23 #include "components/sync/syncable/directory.h" |
24 #include "sync/syncable/model_neutral_mutable_entry.h" | 24 #include "components/sync/syncable/entry.h" |
25 #include "sync/syncable/syncable_base_transaction.h" | 25 #include "components/sync/syncable/model_neutral_mutable_entry.h" |
26 #include "sync/syncable/syncable_base_write_transaction.h" | 26 #include "components/sync/syncable/syncable_base_transaction.h" |
27 #include "sync/syncable/syncable_changes_version.h" | 27 #include "components/sync/syncable/syncable_base_write_transaction.h" |
28 #include "sync/syncable/syncable_proto_util.h" | 28 #include "components/sync/syncable/syncable_changes_version.h" |
29 #include "sync/syncable/syncable_util.h" | 29 #include "components/sync/syncable/syncable_proto_util.h" |
30 #include "sync/util/time.h" | 30 #include "components/sync/syncable/syncable_util.h" |
31 | 31 |
32 using std::set; | 32 using std::set; |
33 using std::string; | 33 using std::string; |
34 using std::vector; | 34 using std::vector; |
35 | 35 |
36 namespace syncer { | 36 namespace syncer { |
37 | 37 |
38 using syncable::Entry; | 38 using syncable::Entry; |
39 using syncable::Id; | 39 using syncable::Id; |
40 | 40 |
41 namespace commit_util { | 41 namespace commit_util { |
42 | 42 |
43 void AddExtensionsActivityToMessage( | 43 void AddExtensionsActivityToMessage( |
44 ExtensionsActivity* activity, | 44 ExtensionsActivity* activity, |
45 ExtensionsActivity::Records* extensions_activity_buffer, | 45 ExtensionsActivity::Records* extensions_activity_buffer, |
46 sync_pb::CommitMessage* message) { | 46 sync_pb::CommitMessage* message) { |
47 // This isn't perfect, since the set of extensions activity may not correlate | 47 // This isn't perfect, since the set of extensions activity may not correlate |
48 // exactly with the items being committed. That's OK as long as we're looking | 48 // exactly with the items being committed. That's OK as long as we're looking |
49 // for a rough estimate of extensions activity, not an precise mapping of | 49 // for a rough estimate of extensions activity, not an precise mapping of |
50 // which commits were triggered by which extension. | 50 // which commits were triggered by which extension. |
51 // | 51 // |
52 // We will push this list of extensions activity back into the | 52 // We will push this list of extensions activity back into the |
53 // ExtensionsActivityMonitor if this commit fails. That's why we must keep a | 53 // ExtensionsActivityMonitor if this commit fails. That's why we must keep a |
54 // copy of these records in the session. | 54 // copy of these records in the session. |
55 activity->GetAndClearRecords(extensions_activity_buffer); | 55 activity->GetAndClearRecords(extensions_activity_buffer); |
56 | 56 |
57 const ExtensionsActivity::Records& records = *extensions_activity_buffer; | 57 const ExtensionsActivity::Records& records = *extensions_activity_buffer; |
58 for (ExtensionsActivity::Records::const_iterator it = | 58 for (ExtensionsActivity::Records::const_iterator it = records.begin(); |
59 records.begin(); | |
60 it != records.end(); ++it) { | 59 it != records.end(); ++it) { |
61 sync_pb::ChromiumExtensionsActivity* activity_message = | 60 sync_pb::ChromiumExtensionsActivity* activity_message = |
62 message->add_extensions_activity(); | 61 message->add_extensions_activity(); |
63 activity_message->set_extension_id(it->second.extension_id); | 62 activity_message->set_extension_id(it->second.extension_id); |
64 activity_message->set_bookmark_writes_since_last_commit( | 63 activity_message->set_bookmark_writes_since_last_commit( |
65 it->second.bookmark_write_count); | 64 it->second.bookmark_write_count); |
66 } | 65 } |
67 } | 66 } |
68 | 67 |
69 void AddClientConfigParamsToMessage( | 68 void AddClientConfigParamsToMessage(ModelTypeSet enabled_types, |
70 ModelTypeSet enabled_types, | 69 bool cookie_jar_mismatch, |
71 bool cookie_jar_mismatch, | 70 sync_pb::CommitMessage* message) { |
72 sync_pb::CommitMessage* message) { | |
73 sync_pb::ClientConfigParams* config_params = message->mutable_config_params(); | 71 sync_pb::ClientConfigParams* config_params = message->mutable_config_params(); |
74 for (ModelTypeSet::Iterator it = enabled_types.First(); it.Good(); it.Inc()) { | 72 for (ModelTypeSet::Iterator it = enabled_types.First(); it.Good(); it.Inc()) { |
75 if (ProxyTypes().Has(it.Get())) | 73 if (ProxyTypes().Has(it.Get())) |
76 continue; | 74 continue; |
77 int field_number = GetSpecificsFieldNumberFromModelType(it.Get()); | 75 int field_number = GetSpecificsFieldNumberFromModelType(it.Get()); |
78 config_params->mutable_enabled_type_ids()->Add(field_number); | 76 config_params->mutable_enabled_type_ids()->Add(field_number); |
79 } | 77 } |
80 config_params->set_tabs_datatype_enabled( | 78 config_params->set_tabs_datatype_enabled( |
81 enabled_types.Has(syncer::PROXY_TABS)); | 79 enabled_types.Has(syncer::PROXY_TABS)); |
82 config_params->set_cookie_jar_mismatch(cookie_jar_mismatch); | 80 config_params->set_cookie_jar_mismatch(cookie_jar_mismatch); |
(...skipping 15 matching lines...) Expand all Loading... |
98 sync_pb::SyncEntity* sync_entry) { | 96 sync_pb::SyncEntity* sync_entry) { |
99 const sync_pb::AttachmentMetadata& attachment_metadata = | 97 const sync_pb::AttachmentMetadata& attachment_metadata = |
100 meta_entry.GetAttachmentMetadata(); | 98 meta_entry.GetAttachmentMetadata(); |
101 for (int i = 0; i < attachment_metadata.record_size(); ++i) { | 99 for (int i = 0; i < attachment_metadata.record_size(); ++i) { |
102 *sync_entry->add_attachment_id() = attachment_metadata.record(i).id(); | 100 *sync_entry->add_attachment_id() = attachment_metadata.record(i).id(); |
103 } | 101 } |
104 } | 102 } |
105 | 103 |
106 } // namespace | 104 } // namespace |
107 | 105 |
108 void BuildCommitItem( | 106 void BuildCommitItem(const syncable::Entry& meta_entry, |
109 const syncable::Entry& meta_entry, | 107 sync_pb::SyncEntity* sync_entry) { |
110 sync_pb::SyncEntity* sync_entry) { | |
111 syncable::Id id = meta_entry.GetId(); | 108 syncable::Id id = meta_entry.GetId(); |
112 sync_entry->set_id_string(SyncableIdToProto(id)); | 109 sync_entry->set_id_string(SyncableIdToProto(id)); |
113 | 110 |
114 string name = meta_entry.GetNonUniqueName(); | 111 string name = meta_entry.GetNonUniqueName(); |
115 CHECK(!name.empty()); // Make sure this isn't an update. | 112 CHECK(!name.empty()); // Make sure this isn't an update. |
116 // Note: Truncation is also performed in WriteNode::SetTitle(..). But this | 113 // Note: Truncation is also performed in WriteNode::SetTitle(..). But this |
117 // call is still necessary to handle any title changes that might originate | 114 // call is still necessary to handle any title changes that might originate |
118 // elsewhere, or already be persisted in the directory. | 115 // elsewhere, or already be persisted in the directory. |
119 base::TruncateUTF8ToByteSize(name, 255, &name); | 116 base::TruncateUTF8ToByteSize(name, 255, &name); |
120 sync_entry->set_name(name); | 117 sync_entry->set_name(name); |
121 | 118 |
122 // Set the non_unique_name. If we do, the server ignores | 119 // Set the non_unique_name. If we do, the server ignores |
123 // the |name| value (using |non_unique_name| instead), and will return | 120 // the |name| value (using |non_unique_name| instead), and will return |
124 // in the CommitResponse a unique name if one is generated. | 121 // in the CommitResponse a unique name if one is generated. |
125 // We send both because it may aid in logging. | 122 // We send both because it may aid in logging. |
126 sync_entry->set_non_unique_name(name); | 123 sync_entry->set_non_unique_name(name); |
127 | 124 |
128 if (!meta_entry.GetUniqueClientTag().empty()) { | 125 if (!meta_entry.GetUniqueClientTag().empty()) { |
129 sync_entry->set_client_defined_unique_tag( | 126 sync_entry->set_client_defined_unique_tag(meta_entry.GetUniqueClientTag()); |
130 meta_entry.GetUniqueClientTag()); | |
131 } | 127 } |
132 | 128 |
133 // Deleted items with server-unknown parent ids can be a problem so we set | 129 // Deleted items with server-unknown parent ids can be a problem so we set |
134 // the parent to 0. (TODO(sync): Still true in protocol?). | 130 // the parent to 0. (TODO(sync): Still true in protocol?). |
135 Id new_parent_id; | 131 Id new_parent_id; |
136 if (meta_entry.GetIsDel() && | 132 if (meta_entry.GetIsDel() && !meta_entry.GetParentId().ServerKnows()) { |
137 !meta_entry.GetParentId().ServerKnows()) { | |
138 new_parent_id = syncable::BaseTransaction::root_id(); | 133 new_parent_id = syncable::BaseTransaction::root_id(); |
139 } else { | 134 } else { |
140 new_parent_id = meta_entry.GetParentId(); | 135 new_parent_id = meta_entry.GetParentId(); |
141 } | 136 } |
142 | 137 |
143 if (meta_entry.ShouldMaintainHierarchy()) { | 138 if (meta_entry.ShouldMaintainHierarchy()) { |
144 sync_entry->set_parent_id_string(SyncableIdToProto(new_parent_id)); | 139 sync_entry->set_parent_id_string(SyncableIdToProto(new_parent_id)); |
145 } | 140 } |
146 | 141 |
147 // If our parent has changed, send up the old one so the server | 142 // If our parent has changed, send up the old one so the server |
148 // can correctly deal with multiple parents. | 143 // can correctly deal with multiple parents. |
149 // TODO(nick): With the server keeping track of the primary sync parent, | 144 // TODO(nick): With the server keeping track of the primary sync parent, |
150 // it should not be necessary to provide the old_parent_id: the version | 145 // it should not be necessary to provide the old_parent_id: the version |
151 // number should suffice. | 146 // number should suffice. |
152 Id server_parent_id = meta_entry.GetServerParentId(); | 147 Id server_parent_id = meta_entry.GetServerParentId(); |
153 if (new_parent_id != server_parent_id && !server_parent_id.IsNull() && | 148 if (new_parent_id != server_parent_id && !server_parent_id.IsNull() && |
154 0 != meta_entry.GetBaseVersion() && | 149 0 != meta_entry.GetBaseVersion() && |
155 syncable::CHANGES_VERSION != meta_entry.GetBaseVersion()) { | 150 syncable::CHANGES_VERSION != meta_entry.GetBaseVersion()) { |
156 sync_entry->set_old_parent_id(SyncableIdToProto(server_parent_id)); | 151 sync_entry->set_old_parent_id(SyncableIdToProto(server_parent_id)); |
157 } | 152 } |
158 | 153 |
159 int64_t version = meta_entry.GetBaseVersion(); | 154 int64_t version = meta_entry.GetBaseVersion(); |
160 if (syncable::CHANGES_VERSION == version || 0 == version) { | 155 if (syncable::CHANGES_VERSION == version || 0 == version) { |
161 // Undeletions are only supported for items that have a client tag. | 156 // Undeletions are only supported for items that have a client tag. |
162 DCHECK(!id.ServerKnows() || | 157 DCHECK(!id.ServerKnows() || !meta_entry.GetUniqueClientTag().empty()) |
163 !meta_entry.GetUniqueClientTag().empty()) | |
164 << meta_entry; | 158 << meta_entry; |
165 | 159 |
166 // Version 0 means to create or undelete an object. | 160 // Version 0 means to create or undelete an object. |
167 sync_entry->set_version(0); | 161 sync_entry->set_version(0); |
168 } else { | 162 } else { |
169 DCHECK(id.ServerKnows()) << meta_entry; | 163 DCHECK(id.ServerKnows()) << meta_entry; |
170 sync_entry->set_version(meta_entry.GetBaseVersion()); | 164 sync_entry->set_version(meta_entry.GetBaseVersion()); |
171 } | 165 } |
172 sync_entry->set_ctime(TimeToProtoTime(meta_entry.GetCtime())); | 166 sync_entry->set_ctime(TimeToProtoTime(meta_entry.GetCtime())); |
173 sync_entry->set_mtime(TimeToProtoTime(meta_entry.GetMtime())); | 167 sync_entry->set_mtime(TimeToProtoTime(meta_entry.GetMtime())); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 } | 226 } |
233 | 227 |
234 bool UpdateVersionAfterCommit( | 228 bool UpdateVersionAfterCommit( |
235 const sync_pb::SyncEntity& committed_entry, | 229 const sync_pb::SyncEntity& committed_entry, |
236 const sync_pb::CommitResponse_EntryResponse& entry_response, | 230 const sync_pb::CommitResponse_EntryResponse& entry_response, |
237 const syncable::Id& pre_commit_id, | 231 const syncable::Id& pre_commit_id, |
238 syncable::ModelNeutralMutableEntry* local_entry) { | 232 syncable::ModelNeutralMutableEntry* local_entry) { |
239 int64_t old_version = local_entry->GetBaseVersion(); | 233 int64_t old_version = local_entry->GetBaseVersion(); |
240 int64_t new_version = entry_response.version(); | 234 int64_t new_version = entry_response.version(); |
241 bool bad_commit_version = false; | 235 bool bad_commit_version = false; |
242 if (committed_entry.deleted() && | 236 if (committed_entry.deleted() && !local_entry->GetUniqueClientTag().empty()) { |
243 !local_entry->GetUniqueClientTag().empty()) { | |
244 // If the item was deleted, and it's undeletable (uses the client tag), | 237 // If the item was deleted, and it's undeletable (uses the client tag), |
245 // change the version back to zero. We must set the version to zero so | 238 // change the version back to zero. We must set the version to zero so |
246 // that the server knows to re-create the item if it gets committed | 239 // that the server knows to re-create the item if it gets committed |
247 // later for undeletion. | 240 // later for undeletion. |
248 new_version = 0; | 241 new_version = 0; |
249 } else if (!pre_commit_id.ServerKnows()) { | 242 } else if (!pre_commit_id.ServerKnows()) { |
250 bad_commit_version = 0 == new_version; | 243 bad_commit_version = 0 == new_version; |
251 } else { | 244 } else { |
252 bad_commit_version = old_version > new_version; | 245 bad_commit_version = old_version > new_version; |
253 } | 246 } |
(...skipping 18 matching lines...) Expand all Loading... |
272 const sync_pb::CommitResponse_EntryResponse& entry_response, | 265 const sync_pb::CommitResponse_EntryResponse& entry_response, |
273 const syncable::Id& pre_commit_id, | 266 const syncable::Id& pre_commit_id, |
274 syncable::ModelNeutralMutableEntry* local_entry) { | 267 syncable::ModelNeutralMutableEntry* local_entry) { |
275 syncable::BaseWriteTransaction* trans = local_entry->base_write_transaction(); | 268 syncable::BaseWriteTransaction* trans = local_entry->base_write_transaction(); |
276 const syncable::Id& entry_response_id = | 269 const syncable::Id& entry_response_id = |
277 SyncableIdFromProto(entry_response.id_string()); | 270 SyncableIdFromProto(entry_response.id_string()); |
278 if (entry_response_id != pre_commit_id) { | 271 if (entry_response_id != pre_commit_id) { |
279 if (pre_commit_id.ServerKnows()) { | 272 if (pre_commit_id.ServerKnows()) { |
280 // The server can sometimes generate a new ID on commit; for example, | 273 // The server can sometimes generate a new ID on commit; for example, |
281 // when committing an undeletion. | 274 // when committing an undeletion. |
282 DVLOG(1) << " ID changed while committing an old entry. " | 275 DVLOG(1) << " ID changed while committing an old entry. " << pre_commit_id |
283 << pre_commit_id << " became " << entry_response_id << "."; | 276 << " became " << entry_response_id << "."; |
284 } | 277 } |
285 syncable::ModelNeutralMutableEntry same_id( | 278 syncable::ModelNeutralMutableEntry same_id(trans, syncable::GET_BY_ID, |
286 trans, | 279 entry_response_id); |
287 syncable::GET_BY_ID, | |
288 entry_response_id); | |
289 // We should trap this before this function. | 280 // We should trap this before this function. |
290 if (same_id.good()) { | 281 if (same_id.good()) { |
291 LOG(ERROR) << "ID clash with id " << entry_response_id | 282 LOG(ERROR) << "ID clash with id " << entry_response_id |
292 << " during commit " << same_id; | 283 << " during commit " << same_id; |
293 return false; | 284 return false; |
294 } | 285 } |
295 ChangeEntryIDAndUpdateChildren(trans, local_entry, entry_response_id); | 286 ChangeEntryIDAndUpdateChildren(trans, local_entry, entry_response_id); |
296 DVLOG(1) << "Changing ID to " << entry_response_id; | 287 DVLOG(1) << "Changing ID to " << entry_response_id; |
297 } | 288 } |
298 return true; | 289 return true; |
299 } | 290 } |
300 | 291 |
301 void UpdateServerFieldsAfterCommit( | 292 void UpdateServerFieldsAfterCommit( |
302 const sync_pb::SyncEntity& committed_entry, | 293 const sync_pb::SyncEntity& committed_entry, |
303 const sync_pb::CommitResponse_EntryResponse& entry_response, | 294 const sync_pb::CommitResponse_EntryResponse& entry_response, |
304 syncable::ModelNeutralMutableEntry* local_entry) { | 295 syncable::ModelNeutralMutableEntry* local_entry) { |
305 | |
306 // We just committed an entry successfully, and now we want to make our view | 296 // We just committed an entry successfully, and now we want to make our view |
307 // of the server state consistent with the server state. We must be careful; | 297 // of the server state consistent with the server state. We must be careful; |
308 // |entry_response| and |committed_entry| have some identically named | 298 // |entry_response| and |committed_entry| have some identically named |
309 // fields. We only want to consider fields from |committed_entry| when there | 299 // fields. We only want to consider fields from |committed_entry| when there |
310 // is not an overriding field in the |entry_response|. We do not want to | 300 // is not an overriding field in the |entry_response|. We do not want to |
311 // update the server data from the local data in the entry -- it's possible | 301 // update the server data from the local data in the entry -- it's possible |
312 // that the local data changed during the commit, and even if not, the server | 302 // that the local data changed during the commit, and even if not, the server |
313 // has the last word on the values of several properties. | 303 // has the last word on the values of several properties. |
314 | 304 |
315 local_entry->PutServerIsDel(committed_entry.deleted()); | 305 local_entry->PutServerIsDel(committed_entry.deleted()); |
316 if (committed_entry.deleted()) { | 306 if (committed_entry.deleted()) { |
317 // Don't clobber any other fields of deleted objects. | 307 // Don't clobber any other fields of deleted objects. |
318 return; | 308 return; |
319 } | 309 } |
320 | 310 |
321 local_entry->PutServerIsDir( | 311 local_entry->PutServerIsDir( |
322 (committed_entry.folder() || | 312 (committed_entry.folder() || |
323 committed_entry.bookmarkdata().bookmark_folder())); | 313 committed_entry.bookmarkdata().bookmark_folder())); |
324 local_entry->PutServerSpecifics(committed_entry.specifics()); | 314 local_entry->PutServerSpecifics(committed_entry.specifics()); |
325 local_entry->PutServerAttachmentMetadata( | 315 local_entry->PutServerAttachmentMetadata( |
326 CreateAttachmentMetadata(committed_entry.attachment_id())); | 316 CreateAttachmentMetadata(committed_entry.attachment_id())); |
327 local_entry->PutServerMtime(ProtoTimeToTime(committed_entry.mtime())); | 317 local_entry->PutServerMtime(ProtoTimeToTime(committed_entry.mtime())); |
328 local_entry->PutServerCtime(ProtoTimeToTime(committed_entry.ctime())); | 318 local_entry->PutServerCtime(ProtoTimeToTime(committed_entry.ctime())); |
329 if (committed_entry.has_unique_position()) { | 319 if (committed_entry.has_unique_position()) { |
330 local_entry->PutServerUniquePosition( | 320 local_entry->PutServerUniquePosition( |
331 UniquePosition::FromProto( | 321 UniquePosition::FromProto(committed_entry.unique_position())); |
332 committed_entry.unique_position())); | |
333 } | 322 } |
334 | 323 |
335 // TODO(nick): The server doesn't set entry_response.server_parent_id in | 324 // TODO(nick): The server doesn't set entry_response.server_parent_id in |
336 // practice; to update SERVER_PARENT_ID appropriately here we'd need to | 325 // practice; to update SERVER_PARENT_ID appropriately here we'd need to |
337 // get the post-commit ID of the parent indicated by | 326 // get the post-commit ID of the parent indicated by |
338 // committed_entry.parent_id_string(). That should be inferrable from the | 327 // committed_entry.parent_id_string(). That should be inferrable from the |
339 // information we have, but it's a bit convoluted to pull it out directly. | 328 // information we have, but it's a bit convoluted to pull it out directly. |
340 // Getting this right is important: SERVER_PARENT_ID gets fed back into | 329 // Getting this right is important: SERVER_PARENT_ID gets fed back into |
341 // old_parent_id during the next commit. | 330 // old_parent_id during the next commit. |
342 local_entry->PutServerParentId(local_entry->GetParentId()); | 331 local_entry->PutServerParentId(local_entry->GetParentId()); |
343 local_entry->PutServerNonUniqueName( | 332 local_entry->PutServerNonUniqueName( |
344 GetResultingPostCommitName(committed_entry, entry_response)); | 333 GetResultingPostCommitName(committed_entry, entry_response)); |
345 | 334 |
346 if (local_entry->GetIsUnappliedUpdate()) { | 335 if (local_entry->GetIsUnappliedUpdate()) { |
347 // This shouldn't happen; an unapplied update shouldn't be committed, and | 336 // This shouldn't happen; an unapplied update shouldn't be committed, and |
348 // if it were, the commit should have failed. But if it does happen: we've | 337 // if it were, the commit should have failed. But if it does happen: we've |
349 // just overwritten the update info, so clear the flag. | 338 // just overwritten the update info, so clear the flag. |
350 local_entry->PutIsUnappliedUpdate(false); | 339 local_entry->PutIsUnappliedUpdate(false); |
351 } | 340 } |
352 } | 341 } |
353 | 342 |
354 void ProcessSuccessfulCommitResponse( | 343 void ProcessSuccessfulCommitResponse( |
355 const sync_pb::SyncEntity& committed_entry, | 344 const sync_pb::SyncEntity& committed_entry, |
356 const sync_pb::CommitResponse_EntryResponse& entry_response, | 345 const sync_pb::CommitResponse_EntryResponse& entry_response, |
357 const syncable::Id& pre_commit_id, | 346 const syncable::Id& pre_commit_id, |
358 syncable::ModelNeutralMutableEntry* local_entry, | 347 syncable::ModelNeutralMutableEntry* local_entry, |
359 bool dirty_sync_was_set, set<syncable::Id>* deleted_folders) { | 348 bool dirty_sync_was_set, |
| 349 set<syncable::Id>* deleted_folders) { |
360 DCHECK(local_entry->GetIsUnsynced()); | 350 DCHECK(local_entry->GetIsUnsynced()); |
361 | 351 |
362 // Update SERVER_VERSION and BASE_VERSION. | 352 // Update SERVER_VERSION and BASE_VERSION. |
363 if (!UpdateVersionAfterCommit(committed_entry, entry_response, pre_commit_id, | 353 if (!UpdateVersionAfterCommit(committed_entry, entry_response, pre_commit_id, |
364 local_entry)) { | 354 local_entry)) { |
365 LOG(ERROR) << "Bad version in commit return for " << *local_entry | 355 LOG(ERROR) << "Bad version in commit return for " << *local_entry |
366 << " new_id:" << SyncableIdFromProto(entry_response.id_string()) | 356 << " new_id:" << SyncableIdFromProto(entry_response.id_string()) |
367 << " new_version:" << entry_response.version(); | 357 << " new_version:" << entry_response.version(); |
368 return; | 358 return; |
369 } | 359 } |
(...skipping 24 matching lines...) Expand all Loading... |
394 } | 384 } |
395 | 385 |
396 } // namespace | 386 } // namespace |
397 | 387 |
398 sync_pb::CommitResponse::ResponseType ProcessSingleCommitResponse( | 388 sync_pb::CommitResponse::ResponseType ProcessSingleCommitResponse( |
399 syncable::BaseWriteTransaction* trans, | 389 syncable::BaseWriteTransaction* trans, |
400 const sync_pb::CommitResponse_EntryResponse& server_entry, | 390 const sync_pb::CommitResponse_EntryResponse& server_entry, |
401 const sync_pb::SyncEntity& commit_request_entry, | 391 const sync_pb::SyncEntity& commit_request_entry, |
402 int64_t metahandle, | 392 int64_t metahandle, |
403 set<syncable::Id>* deleted_folders) { | 393 set<syncable::Id>* deleted_folders) { |
404 syncable::ModelNeutralMutableEntry local_entry( | 394 syncable::ModelNeutralMutableEntry local_entry(trans, syncable::GET_BY_HANDLE, |
405 trans, | 395 metahandle); |
406 syncable::GET_BY_HANDLE, | |
407 metahandle); | |
408 CHECK(local_entry.good()); | 396 CHECK(local_entry.good()); |
409 bool dirty_sync_was_set = local_entry.GetDirtySync(); | 397 bool dirty_sync_was_set = local_entry.GetDirtySync(); |
410 local_entry.PutDirtySync(false); | 398 local_entry.PutDirtySync(false); |
411 local_entry.PutSyncing(false); | 399 local_entry.PutSyncing(false); |
412 | 400 |
413 sync_pb::CommitResponse::ResponseType response = server_entry.response_type(); | 401 sync_pb::CommitResponse::ResponseType response = server_entry.response_type(); |
414 if (!sync_pb::CommitResponse::ResponseType_IsValid(response)) { | 402 if (!sync_pb::CommitResponse::ResponseType_IsValid(response)) { |
415 LOG(ERROR) << "Commit response has unknown response type! Possibly out " | 403 LOG(ERROR) << "Commit response has unknown response type! Possibly out " |
416 "of date client?"; | 404 "of date client?"; |
417 return sync_pb::CommitResponse::INVALID_MESSAGE; | 405 return sync_pb::CommitResponse::INVALID_MESSAGE; |
418 } | 406 } |
419 if (sync_pb::CommitResponse::TRANSIENT_ERROR == response) { | 407 if (sync_pb::CommitResponse::TRANSIENT_ERROR == response) { |
420 DVLOG(1) << "Transient Error Committing: " << local_entry; | 408 DVLOG(1) << "Transient Error Committing: " << local_entry; |
421 LogServerError(server_entry); | 409 LogServerError(server_entry); |
422 return sync_pb::CommitResponse::TRANSIENT_ERROR; | 410 return sync_pb::CommitResponse::TRANSIENT_ERROR; |
423 } | 411 } |
424 if (sync_pb::CommitResponse::INVALID_MESSAGE == response) { | 412 if (sync_pb::CommitResponse::INVALID_MESSAGE == response) { |
425 LOG(ERROR) << "Error Commiting: " << local_entry; | 413 LOG(ERROR) << "Error Commiting: " << local_entry; |
426 LogServerError(server_entry); | 414 LogServerError(server_entry); |
(...skipping 18 matching lines...) Expand all Loading... |
445 | 433 |
446 // Implied by the IsValid call above, but here for clarity. | 434 // Implied by the IsValid call above, but here for clarity. |
447 DCHECK_EQ(sync_pb::CommitResponse::SUCCESS, response) << response; | 435 DCHECK_EQ(sync_pb::CommitResponse::SUCCESS, response) << response; |
448 // Check to see if we've been given the ID of an existing entry. If so treat | 436 // Check to see if we've been given the ID of an existing entry. If so treat |
449 // it as an error response and retry later. | 437 // it as an error response and retry later. |
450 const syncable::Id& server_entry_id = | 438 const syncable::Id& server_entry_id = |
451 SyncableIdFromProto(server_entry.id_string()); | 439 SyncableIdFromProto(server_entry.id_string()); |
452 if (local_entry.GetId() != server_entry_id) { | 440 if (local_entry.GetId() != server_entry_id) { |
453 Entry e(trans, syncable::GET_BY_ID, server_entry_id); | 441 Entry e(trans, syncable::GET_BY_ID, server_entry_id); |
454 if (e.good()) { | 442 if (e.good()) { |
455 LOG(ERROR) | 443 LOG(ERROR) << "Got duplicate id when commiting id: " |
456 << "Got duplicate id when commiting id: " | 444 << local_entry.GetId() << ". Treating as an error return"; |
457 << local_entry.GetId() | |
458 << ". Treating as an error return"; | |
459 return sync_pb::CommitResponse::INVALID_MESSAGE; | 445 return sync_pb::CommitResponse::INVALID_MESSAGE; |
460 } | 446 } |
461 } | 447 } |
462 | 448 |
463 if (server_entry.version() == 0) { | 449 if (server_entry.version() == 0) { |
464 LOG(WARNING) << "Server returned a zero version on a commit response."; | 450 LOG(WARNING) << "Server returned a zero version on a commit response."; |
465 } | 451 } |
466 | 452 |
467 ProcessSuccessfulCommitResponse(commit_request_entry, server_entry, | 453 ProcessSuccessfulCommitResponse(commit_request_entry, server_entry, |
468 local_entry.GetId(), &local_entry, dirty_sync_was_set, deleted_folders); | 454 local_entry.GetId(), &local_entry, |
| 455 dirty_sync_was_set, deleted_folders); |
469 return response; | 456 return response; |
470 } | 457 } |
471 | 458 |
472 } // namespace commit_util | 459 } // namespace commit_util |
473 | 460 |
474 } // namespace syncer | 461 } // namespace syncer |
OLD | NEW |