OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/sync/engine/syncer.h" | 5 #include "chrome/browser/sync/engine/syncer.h" |
6 | 6 |
| 7 #include "base/debug/trace_event.h" |
7 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/logging.h" |
8 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
9 #include "base/time.h" | 11 #include "base/time.h" |
10 #include "chrome/browser/sync/engine/apply_updates_command.h" | 12 #include "chrome/browser/sync/engine/apply_updates_command.h" |
11 #include "chrome/browser/sync/engine/build_and_process_conflict_sets_command.h" | 13 #include "chrome/browser/sync/engine/build_and_process_conflict_sets_command.h" |
12 #include "chrome/browser/sync/engine/build_commit_command.h" | 14 #include "chrome/browser/sync/engine/build_commit_command.h" |
13 #include "chrome/browser/sync/engine/cleanup_disabled_types_command.h" | 15 #include "chrome/browser/sync/engine/cleanup_disabled_types_command.h" |
14 #include "chrome/browser/sync/engine/clear_data_command.h" | 16 #include "chrome/browser/sync/engine/clear_data_command.h" |
15 #include "chrome/browser/sync/engine/conflict_resolver.h" | 17 #include "chrome/browser/sync/engine/conflict_resolver.h" |
16 #include "chrome/browser/sync/engine/download_updates_command.h" | 18 #include "chrome/browser/sync/engine/download_updates_command.h" |
17 #include "chrome/browser/sync/engine/get_commit_ids_command.h" | 19 #include "chrome/browser/sync/engine/get_commit_ids_command.h" |
(...skipping 29 matching lines...) Expand all Loading... |
47 using syncable::ScopedDirLookup; | 49 using syncable::ScopedDirLookup; |
48 using syncable::WriteTransaction; | 50 using syncable::WriteTransaction; |
49 | 51 |
50 namespace browser_sync { | 52 namespace browser_sync { |
51 | 53 |
52 using sessions::ScopedSessionContextConflictResolver; | 54 using sessions::ScopedSessionContextConflictResolver; |
53 using sessions::StatusController; | 55 using sessions::StatusController; |
54 using sessions::SyncSession; | 56 using sessions::SyncSession; |
55 using sessions::ConflictProgress; | 57 using sessions::ConflictProgress; |
56 | 58 |
| 59 #define ENUM_CASE(x) case x: return #x |
| 60 const char* SyncerStepToString(const SyncerStep step) |
| 61 { |
| 62 switch (step) { |
| 63 ENUM_CASE(SYNCER_BEGIN); |
| 64 ENUM_CASE(CLEANUP_DISABLED_TYPES); |
| 65 ENUM_CASE(DOWNLOAD_UPDATES); |
| 66 ENUM_CASE(PROCESS_CLIENT_COMMAND); |
| 67 ENUM_CASE(VERIFY_UPDATES); |
| 68 ENUM_CASE(PROCESS_UPDATES); |
| 69 ENUM_CASE(STORE_TIMESTAMPS); |
| 70 ENUM_CASE(APPLY_UPDATES); |
| 71 ENUM_CASE(BUILD_COMMIT_REQUEST); |
| 72 ENUM_CASE(POST_COMMIT_MESSAGE); |
| 73 ENUM_CASE(PROCESS_COMMIT_RESPONSE); |
| 74 ENUM_CASE(BUILD_AND_PROCESS_CONFLICT_SETS); |
| 75 ENUM_CASE(RESOLVE_CONFLICTS); |
| 76 ENUM_CASE(APPLY_UPDATES_TO_RESOLVE_CONFLICTS); |
| 77 ENUM_CASE(CLEAR_PRIVATE_DATA); |
| 78 ENUM_CASE(SYNCER_END); |
| 79 } |
| 80 NOTREACHED(); |
| 81 return ""; |
| 82 } |
| 83 #undef ENUM_CASE |
| 84 |
57 Syncer::ScopedSyncStartStopTracker::ScopedSyncStartStopTracker( | 85 Syncer::ScopedSyncStartStopTracker::ScopedSyncStartStopTracker( |
58 sessions::SyncSession* session) : session_(session) { | 86 sessions::SyncSession* session) : session_(session) { |
59 session_->status_controller()->SetSyncInProgressAndUpdateStartTime(true); | 87 session_->status_controller()->SetSyncInProgressAndUpdateStartTime(true); |
60 } | 88 } |
61 | 89 |
62 Syncer::ScopedSyncStartStopTracker::~ScopedSyncStartStopTracker() { | 90 Syncer::ScopedSyncStartStopTracker::~ScopedSyncStartStopTracker() { |
63 session_->status_controller()->SetSyncInProgressAndUpdateStartTime(false); | 91 session_->status_controller()->SetSyncInProgressAndUpdateStartTime(false); |
64 } | 92 } |
65 | 93 |
66 Syncer::Syncer() | 94 Syncer::Syncer() |
(...skipping 24 matching lines...) Expand all Loading... |
91 } | 119 } |
92 | 120 |
93 ScopedSessionContextConflictResolver scoped(session->context(), | 121 ScopedSessionContextConflictResolver scoped(session->context(), |
94 &resolver_); | 122 &resolver_); |
95 | 123 |
96 ScopedSyncStartStopTracker start_stop_tracker(session); | 124 ScopedSyncStartStopTracker start_stop_tracker(session); |
97 SyncerStep current_step = first_step; | 125 SyncerStep current_step = first_step; |
98 | 126 |
99 SyncerStep next_step = current_step; | 127 SyncerStep next_step = current_step; |
100 while (!ExitRequested()) { | 128 while (!ExitRequested()) { |
| 129 TRACE_EVENT1("sync", "SyncerStateMachine", |
| 130 "state", SyncerStepToString(current_step)); |
| 131 VLOG(1) << "Syncer step:" << SyncerStepToString(current_step); |
| 132 |
101 switch (current_step) { | 133 switch (current_step) { |
102 case SYNCER_BEGIN: | 134 case SYNCER_BEGIN: |
103 VLOG(1) << "Syncer Begin"; | |
104 // This isn't perfect, as we can end up bundling extensions activity | 135 // This isn't perfect, as we can end up bundling extensions activity |
105 // intended for the next session into the current one. We could do a | 136 // intended for the next session into the current one. We could do a |
106 // test-and-reset as with the source, but note that also falls short if | 137 // test-and-reset as with the source, but note that also falls short if |
107 // the commit request fails (e.g. due to lost connection), as we will | 138 // the commit request fails (e.g. due to lost connection), as we will |
108 // fall all the way back to the syncer thread main loop in that case, | 139 // fall all the way back to the syncer thread main loop in that case, |
109 // creating a new session when a connection is established, losing the | 140 // creating a new session when a connection is established, losing the |
110 // records set here on the original attempt. This should provide us | 141 // records set here on the original attempt. This should provide us |
111 // with the right data "most of the time", and we're only using this | 142 // with the right data "most of the time", and we're only using this |
112 // for analysis purposes, so Law of Large Numbers FTW. | 143 // for analysis purposes, so Law of Large Numbers FTW. |
113 session->context()->extensions_monitor()->GetAndClearRecords( | 144 session->context()->extensions_monitor()->GetAndClearRecords( |
114 session->mutable_extensions_activity()); | 145 session->mutable_extensions_activity()); |
115 next_step = CLEANUP_DISABLED_TYPES; | 146 next_step = CLEANUP_DISABLED_TYPES; |
116 break; | 147 break; |
117 case CLEANUP_DISABLED_TYPES: { | 148 case CLEANUP_DISABLED_TYPES: { |
118 VLOG(1) << "Cleaning up disabled types"; | |
119 CleanupDisabledTypesCommand cleanup; | 149 CleanupDisabledTypesCommand cleanup; |
120 cleanup.Execute(session); | 150 cleanup.Execute(session); |
121 next_step = DOWNLOAD_UPDATES; | 151 next_step = DOWNLOAD_UPDATES; |
122 break; | 152 break; |
123 } | 153 } |
124 case DOWNLOAD_UPDATES: { | 154 case DOWNLOAD_UPDATES: { |
125 VLOG(1) << "Downloading Updates"; | |
126 DownloadUpdatesCommand download_updates; | 155 DownloadUpdatesCommand download_updates; |
127 download_updates.Execute(session); | 156 download_updates.Execute(session); |
128 next_step = PROCESS_CLIENT_COMMAND; | 157 next_step = PROCESS_CLIENT_COMMAND; |
129 break; | 158 break; |
130 } | 159 } |
131 case PROCESS_CLIENT_COMMAND: { | 160 case PROCESS_CLIENT_COMMAND: { |
132 VLOG(1) << "Processing Client Command"; | |
133 ProcessClientCommand(session); | 161 ProcessClientCommand(session); |
134 next_step = VERIFY_UPDATES; | 162 next_step = VERIFY_UPDATES; |
135 break; | 163 break; |
136 } | 164 } |
137 case VERIFY_UPDATES: { | 165 case VERIFY_UPDATES: { |
138 VLOG(1) << "Verifying Updates"; | |
139 VerifyUpdatesCommand verify_updates; | 166 VerifyUpdatesCommand verify_updates; |
140 verify_updates.Execute(session); | 167 verify_updates.Execute(session); |
141 next_step = PROCESS_UPDATES; | 168 next_step = PROCESS_UPDATES; |
142 break; | 169 break; |
143 } | 170 } |
144 case PROCESS_UPDATES: { | 171 case PROCESS_UPDATES: { |
145 VLOG(1) << "Processing Updates"; | |
146 ProcessUpdatesCommand process_updates; | 172 ProcessUpdatesCommand process_updates; |
147 process_updates.Execute(session); | 173 process_updates.Execute(session); |
148 next_step = STORE_TIMESTAMPS; | 174 next_step = STORE_TIMESTAMPS; |
149 break; | 175 break; |
150 } | 176 } |
151 case STORE_TIMESTAMPS: { | 177 case STORE_TIMESTAMPS: { |
152 VLOG(1) << "Storing timestamps"; | |
153 StoreTimestampsCommand store_timestamps; | 178 StoreTimestampsCommand store_timestamps; |
154 store_timestamps.Execute(session); | 179 store_timestamps.Execute(session); |
155 // We should download all of the updates before attempting to process | 180 // We should download all of the updates before attempting to process |
156 // them. | 181 // them. |
157 if (session->status_controller()->ServerSaysNothingMoreToDownload() || | 182 if (session->status_controller()->ServerSaysNothingMoreToDownload() || |
158 !session->status_controller()->download_updates_succeeded()) { | 183 !session->status_controller()->download_updates_succeeded()) { |
159 next_step = APPLY_UPDATES; | 184 next_step = APPLY_UPDATES; |
160 } else { | 185 } else { |
161 next_step = DOWNLOAD_UPDATES; | 186 next_step = DOWNLOAD_UPDATES; |
162 } | 187 } |
163 break; | 188 break; |
164 } | 189 } |
165 case APPLY_UPDATES: { | 190 case APPLY_UPDATES: { |
166 VLOG(1) << "Applying Updates"; | |
167 ApplyUpdatesCommand apply_updates; | 191 ApplyUpdatesCommand apply_updates; |
168 apply_updates.Execute(session); | 192 apply_updates.Execute(session); |
169 if (last_step == APPLY_UPDATES) { | 193 if (last_step == APPLY_UPDATES) { |
170 // We're in configuration mode, but we still need to run the | 194 // We're in configuration mode, but we still need to run the |
171 // SYNCER_END step. | 195 // SYNCER_END step. |
172 last_step = SYNCER_END; | 196 last_step = SYNCER_END; |
173 next_step = SYNCER_END; | 197 next_step = SYNCER_END; |
174 } else { | 198 } else { |
175 next_step = BUILD_COMMIT_REQUEST; | 199 next_step = BUILD_COMMIT_REQUEST; |
176 } | 200 } |
177 break; | 201 break; |
178 } | 202 } |
179 // These two steps are combined since they are executed within the same | 203 // These two steps are combined since they are executed within the same |
180 // write transaction. | 204 // write transaction. |
181 case BUILD_COMMIT_REQUEST: { | 205 case BUILD_COMMIT_REQUEST: { |
182 VLOG(1) << "Processing Commit Request"; | |
183 ScopedDirLookup dir(session->context()->directory_manager(), | 206 ScopedDirLookup dir(session->context()->directory_manager(), |
184 session->context()->account_name()); | 207 session->context()->account_name()); |
185 if (!dir.good()) { | 208 if (!dir.good()) { |
186 LOG(ERROR) << "Scoped dir lookup failed!"; | 209 LOG(ERROR) << "Scoped dir lookup failed!"; |
187 return; | 210 return; |
188 } | 211 } |
189 WriteTransaction trans(FROM_HERE, SYNCER, dir); | 212 WriteTransaction trans(FROM_HERE, SYNCER, dir); |
190 sessions::ScopedSetSessionWriteTransaction set_trans(session, &trans); | 213 sessions::ScopedSetSessionWriteTransaction set_trans(session, &trans); |
191 | 214 |
192 VLOG(1) << "Getting the Commit IDs"; | 215 VLOG(1) << "Getting the Commit IDs"; |
193 GetCommitIdsCommand get_commit_ids_command( | 216 GetCommitIdsCommand get_commit_ids_command( |
194 session->context()->max_commit_batch_size()); | 217 session->context()->max_commit_batch_size()); |
195 get_commit_ids_command.Execute(session); | 218 get_commit_ids_command.Execute(session); |
196 | 219 |
197 if (!session->status_controller()->commit_ids().empty()) { | 220 if (!session->status_controller()->commit_ids().empty()) { |
198 VLOG(1) << "Building a commit message"; | 221 VLOG(1) << "Building a commit message"; |
199 BuildCommitCommand build_commit_command; | 222 BuildCommitCommand build_commit_command; |
200 build_commit_command.Execute(session); | 223 build_commit_command.Execute(session); |
201 | 224 |
202 next_step = POST_COMMIT_MESSAGE; | 225 next_step = POST_COMMIT_MESSAGE; |
203 } else { | 226 } else { |
204 next_step = BUILD_AND_PROCESS_CONFLICT_SETS; | 227 next_step = BUILD_AND_PROCESS_CONFLICT_SETS; |
205 } | 228 } |
206 | 229 |
207 break; | 230 break; |
208 } | 231 } |
209 case POST_COMMIT_MESSAGE: { | 232 case POST_COMMIT_MESSAGE: { |
210 VLOG(1) << "Posting a commit request"; | |
211 PostCommitMessageCommand post_commit_command; | 233 PostCommitMessageCommand post_commit_command; |
212 post_commit_command.Execute(session); | 234 post_commit_command.Execute(session); |
213 next_step = PROCESS_COMMIT_RESPONSE; | 235 next_step = PROCESS_COMMIT_RESPONSE; |
214 break; | 236 break; |
215 } | 237 } |
216 case PROCESS_COMMIT_RESPONSE: { | 238 case PROCESS_COMMIT_RESPONSE: { |
217 VLOG(1) << "Processing the commit response"; | |
218 session->status_controller()->reset_num_conflicting_commits(); | 239 session->status_controller()->reset_num_conflicting_commits(); |
219 ProcessCommitResponseCommand process_response_command; | 240 ProcessCommitResponseCommand process_response_command; |
220 process_response_command.Execute(session); | 241 process_response_command.Execute(session); |
221 next_step = BUILD_AND_PROCESS_CONFLICT_SETS; | 242 next_step = BUILD_AND_PROCESS_CONFLICT_SETS; |
222 break; | 243 break; |
223 } | 244 } |
224 case BUILD_AND_PROCESS_CONFLICT_SETS: { | 245 case BUILD_AND_PROCESS_CONFLICT_SETS: { |
225 VLOG(1) << "Building and Processing Conflict Sets"; | |
226 BuildAndProcessConflictSetsCommand build_process_conflict_sets; | 246 BuildAndProcessConflictSetsCommand build_process_conflict_sets; |
227 build_process_conflict_sets.Execute(session); | 247 build_process_conflict_sets.Execute(session); |
228 if (session->status_controller()->conflict_sets_built()) | 248 if (session->status_controller()->conflict_sets_built()) |
229 next_step = SYNCER_END; | 249 next_step = SYNCER_END; |
230 else | 250 else |
231 next_step = RESOLVE_CONFLICTS; | 251 next_step = RESOLVE_CONFLICTS; |
232 break; | 252 break; |
233 } | 253 } |
234 case RESOLVE_CONFLICTS: { | 254 case RESOLVE_CONFLICTS: { |
235 VLOG(1) << "Resolving Conflicts"; | |
236 | 255 |
237 // Trigger the pre_conflict_resolution_closure_, which is a testing | 256 // Trigger the pre_conflict_resolution_closure_, which is a testing |
238 // hook for the unit tests, if it is non-NULL. | 257 // hook for the unit tests, if it is non-NULL. |
239 if (pre_conflict_resolution_closure_) { | 258 if (pre_conflict_resolution_closure_) { |
240 pre_conflict_resolution_closure_->Run(); | 259 pre_conflict_resolution_closure_->Run(); |
241 } | 260 } |
242 | 261 |
243 StatusController* status = session->status_controller(); | 262 StatusController* status = session->status_controller(); |
244 status->reset_conflicts_resolved(); | 263 status->reset_conflicts_resolved(); |
245 ResolveConflictsCommand resolve_conflicts_command; | 264 ResolveConflictsCommand resolve_conflicts_command; |
(...skipping 22 matching lines...) Expand all Loading... |
268 status->TotalNumBlockingConflictingItems(); | 287 status->TotalNumBlockingConflictingItems(); |
269 status->update_conflicts_resolved(before_blocking_conflicting_updates > | 288 status->update_conflicts_resolved(before_blocking_conflicting_updates > |
270 after_blocking_conflicting_updates); | 289 after_blocking_conflicting_updates); |
271 if (status->conflicts_resolved()) | 290 if (status->conflicts_resolved()) |
272 next_step = RESOLVE_CONFLICTS; | 291 next_step = RESOLVE_CONFLICTS; |
273 else | 292 else |
274 next_step = SYNCER_END; | 293 next_step = SYNCER_END; |
275 break; | 294 break; |
276 } | 295 } |
277 case CLEAR_PRIVATE_DATA: { | 296 case CLEAR_PRIVATE_DATA: { |
278 VLOG(1) << "Clear Private Data"; | |
279 ClearDataCommand clear_data_command; | 297 ClearDataCommand clear_data_command; |
280 clear_data_command.Execute(session); | 298 clear_data_command.Execute(session); |
281 next_step = SYNCER_END; | 299 next_step = SYNCER_END; |
282 break; | 300 break; |
283 } | 301 } |
284 case SYNCER_END: { | 302 case SYNCER_END: { |
285 VLOG(1) << "Syncer End"; | |
286 SyncerEndCommand syncer_end_command; | 303 SyncerEndCommand syncer_end_command; |
287 syncer_end_command.Execute(session); | 304 syncer_end_command.Execute(session); |
288 next_step = SYNCER_END; | 305 next_step = SYNCER_END; |
289 break; | 306 break; |
290 } | 307 } |
291 default: | 308 default: |
292 LOG(ERROR) << "Unknown command: " << current_step; | 309 LOG(ERROR) << "Unknown command: " << current_step; |
293 } | 310 } |
294 VLOG(2) << "last step: " << last_step << ", current step: " | 311 VLOG(2) << "last step: " << SyncerStepToString(last_step) << ", " |
295 << current_step << ", next step: " | 312 << "current step: " << SyncerStepToString(current_step) << ", " |
296 << next_step << ", snapshot: " | 313 << "next step: " << SyncerStepToString(next_step) << ", " |
297 << session->TakeSnapshot().ToString(); | 314 << "snapshot: " << session->TakeSnapshot().ToString(); |
298 if (last_step == current_step) | 315 if (last_step == current_step) |
299 break; | 316 break; |
300 current_step = next_step; | 317 current_step = next_step; |
301 } | 318 } |
302 } | 319 } |
303 | 320 |
304 void Syncer::ProcessClientCommand(sessions::SyncSession* session) { | 321 void Syncer::ProcessClientCommand(sessions::SyncSession* session) { |
305 const ClientToServerResponse& response = | 322 const ClientToServerResponse& response = |
306 session->status_controller()->updates_response(); | 323 session->status_controller()->updates_response(); |
307 if (!response.has_client_command()) | 324 if (!response.has_client_command()) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 entry->Put(SERVER_CTIME, Time()); | 365 entry->Put(SERVER_CTIME, Time()); |
349 entry->Put(SERVER_VERSION, 0); | 366 entry->Put(SERVER_VERSION, 0); |
350 entry->Put(SERVER_IS_DIR, false); | 367 entry->Put(SERVER_IS_DIR, false); |
351 entry->Put(SERVER_IS_DEL, false); | 368 entry->Put(SERVER_IS_DEL, false); |
352 entry->Put(IS_UNAPPLIED_UPDATE, false); | 369 entry->Put(IS_UNAPPLIED_UPDATE, false); |
353 entry->Put(SERVER_SPECIFICS, sync_pb::EntitySpecifics::default_instance()); | 370 entry->Put(SERVER_SPECIFICS, sync_pb::EntitySpecifics::default_instance()); |
354 entry->Put(SERVER_POSITION_IN_PARENT, 0); | 371 entry->Put(SERVER_POSITION_IN_PARENT, 0); |
355 } | 372 } |
356 | 373 |
357 } // namespace browser_sync | 374 } // namespace browser_sync |
OLD | NEW |