OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 // |
| 5 // SyncerSession holds the entire state of a single sync cycle; |
| 6 // GetUpdates, Commit, and Conflict Resolution. After said cycle, the |
| 7 // Session may contain items that were unable to be processed because of |
| 8 // errors. |
| 9 // |
| 10 // THIS CLASS PROVIDES NO SYNCHRONIZATION GUARANTEES. |
| 11 |
| 12 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_SESSION_H_ |
| 13 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_SESSION_H_ |
| 14 |
| 15 #include <utility> |
| 16 #include <vector> |
| 17 |
| 18 #include "chrome/browser/sync/engine/net/server_connection_manager.h" |
| 19 #include "chrome/browser/sync/engine/sync_cycle_state.h" |
| 20 #include "chrome/browser/sync/engine/sync_process_state.h" |
| 21 #include "chrome/browser/sync/engine/syncer_status.h" |
| 22 #include "chrome/browser/sync/engine/syncer_types.h" |
| 23 #include "chrome/browser/sync/engine/syncproto.h" |
| 24 #include "chrome/browser/sync/util/event_sys.h" |
| 25 #include "chrome/browser/sync/util/pthread_helpers.h" |
| 26 #include "chrome/browser/sync/util/sync_types.h" |
| 27 #include "testing/gtest/include/gtest/gtest_prod.h" // For FRIEND_TEST |
| 28 |
| 29 namespace browser_sync { |
| 30 |
| 31 class ConflictResolver; |
| 32 class ModelSafeWorker; |
| 33 class ServerConnectionManager; |
| 34 class SyncerStatus; |
| 35 struct SyncerEvent; |
| 36 |
| 37 class SyncerSession { |
| 38 friend class ConflictResolutionView; |
| 39 friend class SyncerStatus; |
| 40 public: |
| 41 // A utility to set the session's write transaction member, |
| 42 // and later clear it when it the utility falls out of scope. |
| 43 class ScopedSetWriteTransaction { |
| 44 public: |
| 45 ScopedSetWriteTransaction(SyncerSession* session, |
| 46 syncable::WriteTransaction* trans) |
| 47 : session_(session) { |
| 48 session_->set_write_transaction(trans); |
| 49 } |
| 50 ~ScopedSetWriteTransaction() { |
| 51 session_->ClearWriteTransaction(); |
| 52 } |
| 53 private: |
| 54 SyncerSession* session_; |
| 55 DISALLOW_COPY_AND_ASSIGN(ScopedSetWriteTransaction); |
| 56 }; |
| 57 |
| 58 SyncerSession(SyncCycleState* cycle_state, SyncProcessState* process_state) |
| 59 : sync_process_state_(process_state), |
| 60 sync_cycle_state_(cycle_state), |
| 61 source_(sync_pb::GetUpdatesCallerInfo::UNKNOWN), |
| 62 notifications_enabled_(false) { |
| 63 DCHECK(NULL != process_state); |
| 64 DCHECK(NULL != cycle_state); |
| 65 } |
| 66 |
| 67 // Perhaps this should dictate the next step. (ie, don't do apply if you |
| 68 // didn't get any from download). or put it in the while loop. |
| 69 void set_update_response(const ClientToServerResponse& update_response) { |
| 70 sync_cycle_state_->set_update_response(update_response); |
| 71 } |
| 72 |
| 73 const ClientToServerResponse& update_response() const { |
| 74 return sync_cycle_state_->update_response(); |
| 75 } |
| 76 |
| 77 void set_commit_response(const ClientToServerResponse& commit_response) { |
| 78 sync_cycle_state_->set_commit_response(commit_response); |
| 79 } |
| 80 |
| 81 const ClientToServerResponse& commit_response() const { |
| 82 return sync_cycle_state_->commit_response(); |
| 83 } |
| 84 |
| 85 void AddVerifyResult(const VerifyResult& verify_result, |
| 86 const sync_pb::SyncEntity& entity) { |
| 87 sync_cycle_state_->AddVerifyResult(verify_result, entity); |
| 88 } |
| 89 |
| 90 bool HasVerifiedUpdates() const { |
| 91 return sync_cycle_state_->HasVerifiedUpdates(); |
| 92 } |
| 93 |
| 94 void AddAppliedUpdate(const UpdateAttemptResponse& response, |
| 95 const syncable::Id& id) { |
| 96 sync_cycle_state_->AddAppliedUpdate(response, id); |
| 97 } |
| 98 |
| 99 bool HasAppliedUpdates() const { |
| 100 return sync_cycle_state_->HasAppliedUpdates(); |
| 101 } |
| 102 |
| 103 PathString account_name() const { |
| 104 return sync_process_state_->account_name(); |
| 105 } |
| 106 |
| 107 syncable::DirectoryManager* dirman() const { |
| 108 return sync_process_state_->dirman(); |
| 109 } |
| 110 |
| 111 ServerConnectionManager* connection_manager() const { |
| 112 return sync_process_state_->connection_manager(); |
| 113 } |
| 114 |
| 115 ConflictResolver* resolver() const { |
| 116 return sync_process_state_->resolver(); |
| 117 } |
| 118 |
| 119 SyncerEventChannel* syncer_event_channel() const { |
| 120 return sync_process_state_->syncer_event_channel(); |
| 121 } |
| 122 |
| 123 int conflicting_update_count() const { |
| 124 return sync_process_state_->conflicting_updates(); |
| 125 } |
| 126 |
| 127 time_t silenced_until() const { |
| 128 return sync_process_state_->silenced_until_; |
| 129 } |
| 130 |
| 131 void set_silenced_until(time_t silenced_until) const { |
| 132 sync_process_state_->silenced_until_ = silenced_until; |
| 133 } |
| 134 |
| 135 const std::vector<int64>& unsynced_handles() const { |
| 136 return sync_cycle_state_->unsynced_handles(); |
| 137 } |
| 138 |
| 139 void set_unsynced_handles(const std::vector<int64>& unsynced_handles) { |
| 140 sync_cycle_state_->set_unsynced_handles(unsynced_handles); |
| 141 } |
| 142 |
| 143 int64 unsynced_count() const { return sync_cycle_state_->unsynced_count(); } |
| 144 |
| 145 const std::vector<syncable::Id>& commit_ids() const { |
| 146 return sync_cycle_state_->commit_ids(); |
| 147 } |
| 148 |
| 149 void set_commit_ids(const std::vector<syncable::Id>& commit_ids) { |
| 150 sync_cycle_state_->set_commit_ids(commit_ids); |
| 151 } |
| 152 |
| 153 bool commit_ids_empty() const { |
| 154 return sync_cycle_state_->commit_ids_empty(); |
| 155 } |
| 156 |
| 157 syncable::WriteTransaction* write_transaction() const { |
| 158 return sync_cycle_state_->write_transaction(); |
| 159 } |
| 160 |
| 161 bool has_open_write_transaction() const { |
| 162 return sync_cycle_state_->has_open_write_transaction(); |
| 163 } |
| 164 |
| 165 ClientToServerMessage* commit_message() const { |
| 166 return sync_cycle_state_->commit_message(); |
| 167 } |
| 168 |
| 169 void set_commit_message(const ClientToServerMessage& message) { |
| 170 sync_cycle_state_->set_commit_message(message); |
| 171 } |
| 172 |
| 173 bool HasRemainingItemsToCommit() const { |
| 174 return commit_ids().size() < unsynced_handles().size(); |
| 175 } |
| 176 |
| 177 void AddCommitConflict(const syncable::Id& the_id) { |
| 178 sync_process_state_->AddConflictingItem(the_id); |
| 179 } |
| 180 |
| 181 void AddBlockedItem(const syncable::Id& the_id) { |
| 182 sync_process_state_->AddBlockedItem(the_id); |
| 183 } |
| 184 |
| 185 void EraseCommitConflict(const syncable::Id& the_id) { |
| 186 sync_process_state_->EraseConflictingItem(the_id); |
| 187 } |
| 188 |
| 189 void EraseBlockedItem(const syncable::Id& the_id) { |
| 190 sync_process_state_->EraseBlockedItem(the_id); |
| 191 } |
| 192 |
| 193 // Returns true if at least one update application failed due to |
| 194 // a conflict during this sync cycle. |
| 195 bool HasConflictingUpdates() const { |
| 196 std::vector<AppliedUpdate>::const_iterator it; |
| 197 for (it = sync_cycle_state_->AppliedUpdatesBegin(); |
| 198 it < sync_cycle_state_->AppliedUpdatesEnd(); |
| 199 ++it) { |
| 200 if (it->first == CONFLICT) { |
| 201 return true; |
| 202 } |
| 203 } |
| 204 return false; |
| 205 } |
| 206 |
| 207 std::vector<VerifiedUpdate>::iterator VerifiedUpdatesBegin() const { |
| 208 return sync_cycle_state_->VerifiedUpdatesBegin(); |
| 209 } |
| 210 |
| 211 std::vector<VerifiedUpdate>::iterator VerifiedUpdatesEnd() const { |
| 212 return sync_cycle_state_->VerifiedUpdatesEnd(); |
| 213 } |
| 214 |
| 215 // Returns the number of updates received from the sync server. |
| 216 int64 CountUpdates() const { |
| 217 if (update_response().has_get_updates()) { |
| 218 return update_response().get_updates().entries().size(); |
| 219 } else { |
| 220 return 0; |
| 221 } |
| 222 } |
| 223 |
| 224 bool got_zero_updates() const { |
| 225 return CountUpdates() == 0; |
| 226 } |
| 227 |
| 228 void DumpSessionInfo() const { |
| 229 LOG(INFO) << "Dumping session info"; |
| 230 if (update_response().has_get_updates()) { |
| 231 LOG(INFO) << update_response().get_updates().entries().size() |
| 232 << " updates downloaded by last get_updates"; |
| 233 } else { |
| 234 LOG(INFO) << "No update response found"; |
| 235 } |
| 236 LOG(INFO) << sync_cycle_state_->VerifiedUpdatesSize() |
| 237 << " updates verified"; |
| 238 LOG(INFO) << sync_cycle_state_->AppliedUpdatesSize() << " updates applied"; |
| 239 LOG(INFO) << count_blocked_updates() << " updates blocked by open entry"; |
| 240 LOG(INFO) << commit_ids().size() << " items to commit"; |
| 241 LOG(INFO) << unsynced_count() << " unsynced items"; |
| 242 } |
| 243 |
| 244 int64 count_blocked_updates() const { |
| 245 std::vector<AppliedUpdate>::const_iterator it; |
| 246 int64 count = 0; |
| 247 for (it = sync_cycle_state_->AppliedUpdatesBegin(); |
| 248 it < sync_cycle_state_->AppliedUpdatesEnd(); |
| 249 ++it) { |
| 250 if (it->first == BLOCKED) { |
| 251 ++count; |
| 252 } |
| 253 } |
| 254 return count; |
| 255 } |
| 256 |
| 257 void set_conflict_sets_built(const bool b) { |
| 258 sync_cycle_state_->set_conflict_sets_built(b); |
| 259 } |
| 260 |
| 261 bool conflict_sets_built() const { |
| 262 return sync_cycle_state_->conflict_sets_built(); |
| 263 } |
| 264 |
| 265 void set_conflicts_resolved(const bool b) { |
| 266 sync_cycle_state_->set_conflicts_resolved(b); |
| 267 } |
| 268 |
| 269 bool conflicts_resolved() const { |
| 270 return sync_cycle_state_->conflicts_resolved(); |
| 271 } |
| 272 |
| 273 ModelSafeWorker* model_safe_worker() const { |
| 274 return sync_process_state_->model_safe_worker(); |
| 275 } |
| 276 |
| 277 void set_items_committed(const bool b) { |
| 278 sync_cycle_state_->set_items_committed(b); |
| 279 } |
| 280 |
| 281 void set_item_committed() { |
| 282 sync_cycle_state_->set_item_committed(); |
| 283 } |
| 284 |
| 285 bool items_committed() const { |
| 286 return sync_cycle_state_->items_committed(); |
| 287 } |
| 288 |
| 289 void set_over_quota(const bool b) { |
| 290 sync_cycle_state_->set_over_quota(b); |
| 291 } |
| 292 |
| 293 // Volitile reader for the source member of the syncer session object. The |
| 294 // value is set to the SYNC_CYCLE_CONTINUATION value to signal that it has |
| 295 // been read. |
| 296 sync_pb::GetUpdatesCallerInfo::GET_UPDATES_SOURCE TestAndSetSource() { |
| 297 sync_pb::GetUpdatesCallerInfo::GET_UPDATES_SOURCE old_source = |
| 298 source_; |
| 299 set_source(sync_pb::GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION); |
| 300 return old_source; |
| 301 } |
| 302 |
| 303 void set_source(sync_pb::GetUpdatesCallerInfo::GET_UPDATES_SOURCE source) { |
| 304 source_ = source; |
| 305 } |
| 306 |
| 307 bool notifications_enabled() const { |
| 308 return notifications_enabled_; |
| 309 } |
| 310 |
| 311 void set_notifications_enabled(const bool state) { |
| 312 notifications_enabled_ = state; |
| 313 } |
| 314 |
| 315 void set_timestamp_dirty() { |
| 316 sync_cycle_state_->set_timestamp_dirty(); |
| 317 } |
| 318 |
| 319 bool timestamp_dirty() const { |
| 320 return sync_cycle_state_->is_timestamp_dirty(); |
| 321 } |
| 322 |
| 323 // TODO(chron): Unit test for this method. |
| 324 // returns true iff this session contains data that should go through |
| 325 // the sync engine again. |
| 326 bool ShouldSyncAgain() const { |
| 327 return (HasRemainingItemsToCommit() && |
| 328 sync_process_state_->successful_commits() > 0) || |
| 329 conflict_sets_built() || |
| 330 conflicts_resolved() || |
| 331 // Or, we have conflicting updates, but we're making progress on |
| 332 // resolving them... |
| 333 !got_zero_updates() || |
| 334 timestamp_dirty(); |
| 335 } |
| 336 |
| 337 private: |
| 338 // The write transaction must be destructed by the caller of this function. |
| 339 // Here, we just clear the reference. |
| 340 void set_write_transaction(syncable::WriteTransaction* write_transaction) { |
| 341 sync_cycle_state_->set_write_transaction(write_transaction); |
| 342 } |
| 343 |
| 344 // sets the write transaction to null, but doesn't free the memory. |
| 345 void ClearWriteTransaction() { |
| 346 sync_cycle_state_->ClearWriteTransaction(); |
| 347 } |
| 348 |
| 349 SyncProcessState* sync_process_state_; |
| 350 SyncCycleState* sync_cycle_state_; |
| 351 |
| 352 // The source for initiating this syncer session. |
| 353 sync_pb::GetUpdatesCallerInfo::GET_UPDATES_SOURCE source_; |
| 354 |
| 355 // True if notifications are enabled when this session was created. |
| 356 bool notifications_enabled_; |
| 357 |
| 358 FRIEND_TEST(SyncerTest, TestCommitListOrderingCounterexample); |
| 359 DISALLOW_COPY_AND_ASSIGN(SyncerSession); |
| 360 }; |
| 361 |
| 362 } // namespace browser_sync |
| 363 |
| 364 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_SESSION_H_ |
OLD | NEW |