| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // The 'sessions' namespace comprises all the pieces of state that are | |
| 6 // combined to form a SyncSession instance. In that way, it can be thought of | |
| 7 // as an extension of the SyncSession type itself. Session scoping gives | |
| 8 // context to things like "conflict progress", "update progress", etc, and the | |
| 9 // separation this file provides allows clients to only include the parts they | |
| 10 // need rather than the entire session stack. | |
| 11 | |
| 12 #ifndef CHROME_BROWSER_SYNC_SESSIONS_SESSION_STATE_H_ | |
| 13 #define CHROME_BROWSER_SYNC_SESSIONS_SESSION_STATE_H_ | |
| 14 #pragma once | |
| 15 | |
| 16 #include <map> | |
| 17 #include <set> | |
| 18 #include <string> | |
| 19 #include <utility> | |
| 20 #include <vector> | |
| 21 | |
| 22 #include "base/basictypes.h" | |
| 23 #include "chrome/browser/sync/engine/syncer_types.h" | |
| 24 #include "chrome/browser/sync/engine/syncproto.h" | |
| 25 #include "chrome/browser/sync/sessions/ordered_commit_set.h" | |
| 26 #include "chrome/browser/sync/protocol/sync_protocol_error.h" | |
| 27 #include "chrome/browser/sync/syncable/model_type.h" | |
| 28 #include "chrome/browser/sync/syncable/model_type_payload_map.h" | |
| 29 #include "chrome/browser/sync/syncable/syncable.h" | |
| 30 | |
| 31 namespace base { | |
| 32 class DictionaryValue; | |
| 33 } | |
| 34 | |
| 35 namespace browser_sync { | |
| 36 namespace sessions { | |
| 37 | |
| 38 class UpdateProgress; | |
| 39 | |
| 40 // A container for the source of a sync session. This includes the update | |
| 41 // source, the datatypes triggering the sync session, and possible session | |
| 42 // specific payloads which should be sent to the server. | |
| 43 struct SyncSourceInfo { | |
| 44 SyncSourceInfo(); | |
| 45 explicit SyncSourceInfo(const syncable::ModelTypePayloadMap& t); | |
| 46 SyncSourceInfo( | |
| 47 const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& u, | |
| 48 const syncable::ModelTypePayloadMap& t); | |
| 49 ~SyncSourceInfo(); | |
| 50 | |
| 51 // Caller takes ownership of the returned dictionary. | |
| 52 base::DictionaryValue* ToValue() const; | |
| 53 | |
| 54 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource updates_source; | |
| 55 syncable::ModelTypePayloadMap types; | |
| 56 }; | |
| 57 | |
| 58 // Data pertaining to the status of an active Syncer object. | |
| 59 struct SyncerStatus { | |
| 60 SyncerStatus(); | |
| 61 ~SyncerStatus(); | |
| 62 | |
| 63 // Caller takes ownership of the returned dictionary. | |
| 64 base::DictionaryValue* ToValue() const; | |
| 65 | |
| 66 // True when we get such an INVALID_STORE error from the server. | |
| 67 bool invalid_store; | |
| 68 int num_successful_commits; | |
| 69 // This is needed for monitoring extensions activity. | |
| 70 int num_successful_bookmark_commits; | |
| 71 | |
| 72 // Download event counters. | |
| 73 int num_updates_downloaded_total; | |
| 74 int num_tombstone_updates_downloaded_total; | |
| 75 | |
| 76 // If the syncer encountered a MIGRATION_DONE code, these are the types that | |
| 77 // the client must now "migrate", by purging and re-downloading all updates. | |
| 78 syncable::ModelTypeSet types_needing_local_migration; | |
| 79 | |
| 80 // Overwrites due to conflict resolution counters. | |
| 81 int num_local_overwrites; | |
| 82 int num_server_overwrites; | |
| 83 }; | |
| 84 | |
| 85 // Counters for various errors that can occur repeatedly during a sync session. | |
| 86 // TODO(lipalani) : Rename this structure to Error. | |
| 87 struct ErrorCounters { | |
| 88 ErrorCounters(); | |
| 89 | |
| 90 // Any protocol errors that we received during this sync session. | |
| 91 SyncProtocolError sync_protocol_error; | |
| 92 | |
| 93 // Records the most recent results of PostCommit and GetUpdates commands. | |
| 94 SyncerError last_download_updates_result; | |
| 95 SyncerError last_post_commit_result; | |
| 96 SyncerError last_process_commit_response_result; | |
| 97 }; | |
| 98 | |
| 99 // Caller takes ownership of the returned dictionary. | |
| 100 base::DictionaryValue* DownloadProgressMarkersToValue( | |
| 101 const std::string | |
| 102 (&download_progress_markers)[syncable::MODEL_TYPE_COUNT]); | |
| 103 | |
| 104 // An immutable snapshot of state from a SyncSession. Convenient to use as | |
| 105 // part of notifications as it is inherently thread-safe. | |
| 106 struct SyncSessionSnapshot { | |
| 107 SyncSessionSnapshot( | |
| 108 const SyncerStatus& syncer_status, | |
| 109 const ErrorCounters& errors, | |
| 110 int64 num_server_changes_remaining, | |
| 111 bool is_share_usable, | |
| 112 syncable::ModelTypeSet initial_sync_ended, | |
| 113 const std::string | |
| 114 (&download_progress_markers)[syncable::MODEL_TYPE_COUNT], | |
| 115 bool more_to_sync, | |
| 116 bool is_silenced, | |
| 117 int64 unsynced_count, | |
| 118 int num_encryption_conflicts, | |
| 119 int num_hierarchy_conflicts, | |
| 120 int num_simple_conflicts, | |
| 121 int num_server_conflicts, | |
| 122 bool did_commit_items, | |
| 123 const SyncSourceInfo& source, | |
| 124 size_t num_entries, | |
| 125 base::Time sync_start_time, | |
| 126 bool retry_scheduled); | |
| 127 ~SyncSessionSnapshot(); | |
| 128 | |
| 129 // Caller takes ownership of the returned dictionary. | |
| 130 base::DictionaryValue* ToValue() const; | |
| 131 | |
| 132 std::string ToString() const; | |
| 133 | |
| 134 const SyncerStatus syncer_status; | |
| 135 const ErrorCounters errors; | |
| 136 const int64 num_server_changes_remaining; | |
| 137 const bool is_share_usable; | |
| 138 const syncable::ModelTypeSet initial_sync_ended; | |
| 139 const std::string download_progress_markers[syncable::MODEL_TYPE_COUNT]; | |
| 140 const bool has_more_to_sync; | |
| 141 const bool is_silenced; | |
| 142 const int64 unsynced_count; | |
| 143 const int num_encryption_conflicts; | |
| 144 const int num_hierarchy_conflicts; | |
| 145 const int num_simple_conflicts; | |
| 146 const int num_server_conflicts; | |
| 147 const bool did_commit_items; | |
| 148 const SyncSourceInfo source; | |
| 149 const size_t num_entries; | |
| 150 base::Time sync_start_time; | |
| 151 const bool retry_scheduled; | |
| 152 }; | |
| 153 | |
| 154 // Tracks progress of conflicts and their resolutions. | |
| 155 class ConflictProgress { | |
| 156 public: | |
| 157 explicit ConflictProgress(bool* dirty_flag); | |
| 158 ~ConflictProgress(); | |
| 159 | |
| 160 bool HasSimpleConflictItem(const syncable::Id &id) const; | |
| 161 | |
| 162 // Various mutators for tracking commit conflicts. | |
| 163 void AddSimpleConflictingItemById(const syncable::Id& the_id); | |
| 164 void EraseSimpleConflictingItemById(const syncable::Id& the_id); | |
| 165 std::set<syncable::Id>::const_iterator SimpleConflictingItemsBegin() const; | |
| 166 std::set<syncable::Id>::const_iterator SimpleConflictingItemsEnd() const; | |
| 167 int SimpleConflictingItemsSize() const { | |
| 168 return simple_conflicting_item_ids_.size(); | |
| 169 } | |
| 170 | |
| 171 // Mutators for unresolvable conflicting items (see description below). | |
| 172 void AddEncryptionConflictingItemById(const syncable::Id& the_id); | |
| 173 int EncryptionConflictingItemsSize() const { | |
| 174 return num_encryption_conflicting_items; | |
| 175 } | |
| 176 | |
| 177 void AddHierarchyConflictingItemById(const syncable::Id& id); | |
| 178 int HierarchyConflictingItemsSize() const { | |
| 179 return num_hierarchy_conflicting_items; | |
| 180 } | |
| 181 | |
| 182 void AddServerConflictingItemById(const syncable::Id& id); | |
| 183 int ServerConflictingItemsSize() const { | |
| 184 return num_server_conflicting_items; | |
| 185 } | |
| 186 | |
| 187 private: | |
| 188 // Conflicts that occur when local and server changes collide and can be | |
| 189 // resolved locally. | |
| 190 std::set<syncable::Id> simple_conflicting_item_ids_; | |
| 191 | |
| 192 // Unresolvable conflicts are not processed by the conflict resolver. We wait | |
| 193 // and hope the server will provide us with an update that resolves these | |
| 194 // conflicts. | |
| 195 std::set<syncable::Id> unresolvable_conflicting_item_ids_; | |
| 196 | |
| 197 size_t num_server_conflicting_items; | |
| 198 size_t num_hierarchy_conflicting_items; | |
| 199 size_t num_encryption_conflicting_items; | |
| 200 | |
| 201 // Whether a conflicting item was added or removed since | |
| 202 // the last call to reset_progress_changed(), if any. In practice this | |
| 203 // points to StatusController::is_dirty_. | |
| 204 bool* dirty_; | |
| 205 }; | |
| 206 | |
| 207 typedef std::pair<VerifyResult, sync_pb::SyncEntity> VerifiedUpdate; | |
| 208 typedef std::pair<UpdateAttemptResponse, syncable::Id> AppliedUpdate; | |
| 209 | |
| 210 // Tracks update application and verification. | |
| 211 class UpdateProgress { | |
| 212 public: | |
| 213 UpdateProgress(); | |
| 214 ~UpdateProgress(); | |
| 215 | |
| 216 void AddVerifyResult(const VerifyResult& verify_result, | |
| 217 const sync_pb::SyncEntity& entity); | |
| 218 | |
| 219 // Log a successful or failing update attempt. | |
| 220 void AddAppliedUpdate(const UpdateAttemptResponse& response, | |
| 221 const syncable::Id& id); | |
| 222 | |
| 223 // Various iterators. | |
| 224 std::vector<AppliedUpdate>::iterator AppliedUpdatesBegin(); | |
| 225 std::vector<VerifiedUpdate>::const_iterator VerifiedUpdatesBegin() const; | |
| 226 std::vector<AppliedUpdate>::const_iterator AppliedUpdatesEnd() const; | |
| 227 std::vector<VerifiedUpdate>::const_iterator VerifiedUpdatesEnd() const; | |
| 228 | |
| 229 // Returns the number of update application attempts. This includes both | |
| 230 // failures and successes. | |
| 231 int AppliedUpdatesSize() const { return applied_updates_.size(); } | |
| 232 int VerifiedUpdatesSize() const { return verified_updates_.size(); } | |
| 233 bool HasVerifiedUpdates() const { return !verified_updates_.empty(); } | |
| 234 bool HasAppliedUpdates() const { return !applied_updates_.empty(); } | |
| 235 void ClearVerifiedUpdates() { verified_updates_.clear(); } | |
| 236 | |
| 237 // Count the number of successful update applications that have happend this | |
| 238 // cycle. Note that if an item is successfully applied twice, it will be | |
| 239 // double counted here. | |
| 240 int SuccessfullyAppliedUpdateCount() const; | |
| 241 | |
| 242 // Returns true if at least one update application failed due to a conflict | |
| 243 // during this sync cycle. | |
| 244 bool HasConflictingUpdates() const; | |
| 245 | |
| 246 private: | |
| 247 // Container for updates that passed verification. | |
| 248 std::vector<VerifiedUpdate> verified_updates_; | |
| 249 | |
| 250 // Stores the result of the various ApplyUpdate attempts we've made. | |
| 251 // May contain duplicate entries. | |
| 252 std::vector<AppliedUpdate> applied_updates_; | |
| 253 }; | |
| 254 | |
| 255 struct SyncCycleControlParameters { | |
| 256 SyncCycleControlParameters() : conflicts_resolved(false), | |
| 257 items_committed(false), | |
| 258 debug_info_sent(false) {} | |
| 259 // Set to true by ResolveConflictsCommand if any forward progress was made. | |
| 260 bool conflicts_resolved; | |
| 261 | |
| 262 // Set to true by PostCommitMessageCommand if any commits were successful. | |
| 263 bool items_committed; | |
| 264 | |
| 265 // True indicates debug info has been sent once this session. | |
| 266 bool debug_info_sent; | |
| 267 }; | |
| 268 | |
| 269 // DirtyOnWrite wraps a value such that any write operation will update a | |
| 270 // specified dirty bit, which can be used to determine if a notification should | |
| 271 // be sent due to state change. | |
| 272 template <typename T> | |
| 273 class DirtyOnWrite { | |
| 274 public: | |
| 275 explicit DirtyOnWrite(bool* dirty) : dirty_(dirty) {} | |
| 276 DirtyOnWrite(bool* dirty, const T& t) : t_(t), dirty_(dirty) {} | |
| 277 T* mutate() { | |
| 278 *dirty_ = true; | |
| 279 return &t_; | |
| 280 } | |
| 281 const T& value() const { return t_; } | |
| 282 private: | |
| 283 T t_; | |
| 284 bool* dirty_; | |
| 285 }; | |
| 286 | |
| 287 // The next 3 structures declare how all the state involved in running a sync | |
| 288 // cycle is divided between global scope (applies to all model types), | |
| 289 // ModelSafeGroup scope (applies to all data types in a group), and single | |
| 290 // model type scope. Within this breakdown, each struct declares which bits | |
| 291 // of state are dirty-on-write and should incur dirty bit updates if changed. | |
| 292 | |
| 293 // Grouping of all state that applies to all model types. Note that some | |
| 294 // components of the global grouping can internally implement finer grained | |
| 295 // scope control (such as OrderedCommitSet), but the top level entity is still | |
| 296 // a singleton with respect to model types. | |
| 297 struct AllModelTypeState { | |
| 298 explicit AllModelTypeState(bool* dirty_flag); | |
| 299 ~AllModelTypeState(); | |
| 300 | |
| 301 // Commits for all model types are bundled together into a single message. | |
| 302 ClientToServerMessage commit_message; | |
| 303 ClientToServerResponse commit_response; | |
| 304 // We GetUpdates for some combination of types at once. | |
| 305 // requested_update_types stores the set of types which were requested. | |
| 306 syncable::ModelTypeSet updates_request_types; | |
| 307 ClientToServerResponse updates_response; | |
| 308 // Used to build the shared commit message. | |
| 309 DirtyOnWrite<std::vector<int64> > unsynced_handles; | |
| 310 DirtyOnWrite<SyncerStatus> syncer_status; | |
| 311 DirtyOnWrite<ErrorCounters> error; | |
| 312 SyncCycleControlParameters control_params; | |
| 313 DirtyOnWrite<int64> num_server_changes_remaining; | |
| 314 OrderedCommitSet commit_set; | |
| 315 }; | |
| 316 | |
| 317 // Grouping of all state that applies to a single ModelSafeGroup. | |
| 318 struct PerModelSafeGroupState { | |
| 319 explicit PerModelSafeGroupState(bool* dirty_flag); | |
| 320 ~PerModelSafeGroupState(); | |
| 321 | |
| 322 UpdateProgress update_progress; | |
| 323 ConflictProgress conflict_progress; | |
| 324 }; | |
| 325 | |
| 326 } // namespace sessions | |
| 327 } // namespace browser_sync | |
| 328 | |
| 329 #endif // CHROME_BROWSER_SYNC_SESSIONS_SESSION_STATE_H_ | |
| OLD | NEW |