OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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/process_commit_response_command.h" | 5 #include "sync/engine/process_commit_response_command.h" |
6 | 6 |
7 #include <cstddef> | 7 #include <cstddef> |
8 #include <set> | 8 #include <set> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 20 matching lines...) Expand all Loading... |
31 namespace syncer { | 31 namespace syncer { |
32 | 32 |
33 using sessions::OrderedCommitSet; | 33 using sessions::OrderedCommitSet; |
34 using sessions::StatusController; | 34 using sessions::StatusController; |
35 using sessions::SyncSession; | 35 using sessions::SyncSession; |
36 using syncable::WriteTransaction; | 36 using syncable::WriteTransaction; |
37 using syncable::MutableEntry; | 37 using syncable::MutableEntry; |
38 using syncable::Entry; | 38 using syncable::Entry; |
39 using syncable::BASE_VERSION; | 39 using syncable::BASE_VERSION; |
40 using syncable::GET_BY_ID; | 40 using syncable::GET_BY_ID; |
| 41 using syncable::GET_BY_HANDLE; |
41 using syncable::ID; | 42 using syncable::ID; |
42 using syncable::IS_DEL; | 43 using syncable::IS_DEL; |
43 using syncable::IS_DIR; | 44 using syncable::IS_DIR; |
44 using syncable::IS_UNAPPLIED_UPDATE; | 45 using syncable::IS_UNAPPLIED_UPDATE; |
45 using syncable::IS_UNSYNCED; | 46 using syncable::IS_UNSYNCED; |
46 using syncable::PARENT_ID; | 47 using syncable::PARENT_ID; |
47 using syncable::SERVER_IS_DEL; | 48 using syncable::SERVER_IS_DEL; |
48 using syncable::SERVER_PARENT_ID; | 49 using syncable::SERVER_PARENT_ID; |
49 using syncable::SERVER_VERSION; | 50 using syncable::SERVER_VERSION; |
50 using syncable::SYNCER; | 51 using syncable::SYNCER; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 OrderedCommitSet::Projection proj = status->commit_id_projection( | 94 OrderedCommitSet::Projection proj = status->commit_id_projection( |
94 commit_set_); | 95 commit_set_); |
95 | 96 |
96 if (!proj.empty()) { // Scope for WriteTransaction. | 97 if (!proj.empty()) { // Scope for WriteTransaction. |
97 WriteTransaction trans(FROM_HERE, SYNCER, dir); | 98 WriteTransaction trans(FROM_HERE, SYNCER, dir); |
98 for (size_t i = 0; i < proj.size(); i++) { | 99 for (size_t i = 0; i < proj.size(); i++) { |
99 CommitResponse::ResponseType response_type = ProcessSingleCommitResponse( | 100 CommitResponse::ResponseType response_type = ProcessSingleCommitResponse( |
100 &trans, | 101 &trans, |
101 cr.entryresponse(proj[i]), | 102 cr.entryresponse(proj[i]), |
102 commit_message.entries(proj[i]), | 103 commit_message.entries(proj[i]), |
103 commit_set_.GetCommitIdAt(proj[i]), | 104 commit_set_.GetCommitHandleAt(proj[i]), |
104 &deleted_folders); | 105 &deleted_folders); |
105 switch (response_type) { | 106 switch (response_type) { |
106 case CommitResponse::INVALID_MESSAGE: | 107 case CommitResponse::INVALID_MESSAGE: |
107 ++error_commits; | 108 ++error_commits; |
108 break; | 109 break; |
109 case CommitResponse::CONFLICT: | 110 case CommitResponse::CONFLICT: |
110 ++conflicting_commits; | 111 ++conflicting_commits; |
111 status->increment_num_server_conflicts(); | 112 status->increment_num_server_conflicts(); |
112 break; | 113 break; |
113 case CommitResponse::SUCCESS: | 114 case CommitResponse::SUCCESS: |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 LOG(WARNING) << " " << res.error_message(); | 162 LOG(WARNING) << " " << res.error_message(); |
162 else | 163 else |
163 LOG(WARNING) << " No detailed error message returned from server"; | 164 LOG(WARNING) << " No detailed error message returned from server"; |
164 } | 165 } |
165 | 166 |
166 CommitResponse::ResponseType | 167 CommitResponse::ResponseType |
167 ProcessCommitResponseCommand::ProcessSingleCommitResponse( | 168 ProcessCommitResponseCommand::ProcessSingleCommitResponse( |
168 syncable::WriteTransaction* trans, | 169 syncable::WriteTransaction* trans, |
169 const sync_pb::CommitResponse_EntryResponse& server_entry, | 170 const sync_pb::CommitResponse_EntryResponse& server_entry, |
170 const sync_pb::SyncEntity& commit_request_entry, | 171 const sync_pb::SyncEntity& commit_request_entry, |
171 const syncable::Id& pre_commit_id, | 172 const int64 metahandle, |
172 set<syncable::Id>* deleted_folders) { | 173 set<syncable::Id>* deleted_folders) { |
173 | 174 MutableEntry local_entry(trans, GET_BY_HANDLE, metahandle); |
174 MutableEntry local_entry(trans, GET_BY_ID, pre_commit_id); | |
175 CHECK(local_entry.good()); | 175 CHECK(local_entry.good()); |
176 bool syncing_was_set = local_entry.Get(SYNCING); | 176 bool syncing_was_set = local_entry.Get(SYNCING); |
177 local_entry.Put(SYNCING, false); | 177 local_entry.Put(SYNCING, false); |
178 | 178 |
179 CommitResponse::ResponseType response = (CommitResponse::ResponseType) | 179 CommitResponse::ResponseType response = (CommitResponse::ResponseType) |
180 server_entry.response_type(); | 180 server_entry.response_type(); |
181 if (!CommitResponse::ResponseType_IsValid(response)) { | 181 if (!CommitResponse::ResponseType_IsValid(response)) { |
182 LOG(ERROR) << "Commit response has unknown response type! Possibly out " | 182 LOG(ERROR) << "Commit response has unknown response type! Possibly out " |
183 "of date client?"; | 183 "of date client?"; |
184 return CommitResponse::INVALID_MESSAGE; | 184 return CommitResponse::INVALID_MESSAGE; |
(...skipping 24 matching lines...) Expand all Loading... |
209 LOG(ERROR) << "Commit response has no id"; | 209 LOG(ERROR) << "Commit response has no id"; |
210 return CommitResponse::INVALID_MESSAGE; | 210 return CommitResponse::INVALID_MESSAGE; |
211 } | 211 } |
212 | 212 |
213 // Implied by the IsValid call above, but here for clarity. | 213 // Implied by the IsValid call above, but here for clarity. |
214 DCHECK_EQ(CommitResponse::SUCCESS, response) << response; | 214 DCHECK_EQ(CommitResponse::SUCCESS, response) << response; |
215 // Check to see if we've been given the ID of an existing entry. If so treat | 215 // Check to see if we've been given the ID of an existing entry. If so treat |
216 // it as an error response and retry later. | 216 // it as an error response and retry later. |
217 const syncable::Id& server_entry_id = | 217 const syncable::Id& server_entry_id = |
218 SyncableIdFromProto(server_entry.id_string()); | 218 SyncableIdFromProto(server_entry.id_string()); |
219 if (pre_commit_id != server_entry_id) { | 219 if (local_entry.Get(ID) != server_entry_id) { |
220 Entry e(trans, GET_BY_ID, server_entry_id); | 220 Entry e(trans, GET_BY_ID, server_entry_id); |
221 if (e.good()) { | 221 if (e.good()) { |
222 LOG(ERROR) << "Got duplicate id when commiting id: " << pre_commit_id << | 222 LOG(ERROR) |
223 ". Treating as an error return"; | 223 << "Got duplicate id when commiting id: " |
| 224 << local_entry.Get(ID) |
| 225 << ". Treating as an error return"; |
224 return CommitResponse::INVALID_MESSAGE; | 226 return CommitResponse::INVALID_MESSAGE; |
225 } | 227 } |
226 } | 228 } |
227 | 229 |
228 if (server_entry.version() == 0) { | 230 if (server_entry.version() == 0) { |
229 LOG(WARNING) << "Server returned a zero version on a commit response."; | 231 LOG(WARNING) << "Server returned a zero version on a commit response."; |
230 } | 232 } |
231 | 233 |
232 ProcessSuccessfulCommitResponse(commit_request_entry, server_entry, | 234 ProcessSuccessfulCommitResponse(commit_request_entry, server_entry, |
233 pre_commit_id, &local_entry, syncing_was_set, deleted_folders); | 235 local_entry.Get(ID), &local_entry, syncing_was_set, deleted_folders); |
234 return response; | 236 return response; |
235 } | 237 } |
236 | 238 |
237 const string& ProcessCommitResponseCommand::GetResultingPostCommitName( | 239 const string& ProcessCommitResponseCommand::GetResultingPostCommitName( |
238 const sync_pb::SyncEntity& committed_entry, | 240 const sync_pb::SyncEntity& committed_entry, |
239 const sync_pb::CommitResponse_EntryResponse& entry_response) { | 241 const sync_pb::CommitResponse_EntryResponse& entry_response) { |
240 const string& response_name = | 242 const string& response_name = |
241 SyncerProtoUtil::NameFromCommitEntryResponse(entry_response); | 243 SyncerProtoUtil::NameFromCommitEntryResponse(entry_response); |
242 if (!response_name.empty()) | 244 if (!response_name.empty()) |
243 return response_name; | 245 return response_name; |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 // been recursively deleted. | 427 // been recursively deleted. |
426 // TODO(nick): Here, commit_message.deleted() would be more correct than | 428 // TODO(nick): Here, commit_message.deleted() would be more correct than |
427 // local_entry->Get(IS_DEL). For example, an item could be renamed, and then | 429 // local_entry->Get(IS_DEL). For example, an item could be renamed, and then |
428 // deleted during the commit of the rename. Unit test & fix. | 430 // deleted during the commit of the rename. Unit test & fix. |
429 if (local_entry->Get(IS_DIR) && local_entry->Get(IS_DEL)) { | 431 if (local_entry->Get(IS_DIR) && local_entry->Get(IS_DEL)) { |
430 deleted_folders->insert(local_entry->Get(ID)); | 432 deleted_folders->insert(local_entry->Get(ID)); |
431 } | 433 } |
432 } | 434 } |
433 | 435 |
434 } // namespace syncer | 436 } // namespace syncer |
OLD | NEW |