summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/engine/sync_process_state.h
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/sync/engine/sync_process_state.h')
-rw-r--r--chrome/browser/sync/engine/sync_process_state.h384
1 files changed, 384 insertions, 0 deletions
diff --git a/chrome/browser/sync/engine/sync_process_state.h b/chrome/browser/sync/engine/sync_process_state.h
new file mode 100644
index 0000000..32c6808
--- /dev/null
+++ b/chrome/browser/sync/engine/sync_process_state.h
@@ -0,0 +1,384 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//
+// The sync process consists of a sequence of sync cycles, each of which
+// (hopefully) moves the client into closer synchronization with the server.
+// While SyncCycleState holds state that is pertinent to a single sync cycle,
+// this data structure holds state that must be passed from cycle to cycle.
+//
+// THIS CLASS PROVIDES NO SYNCHRONIZATION GUARANTEES.
+
+#ifndef CHROME_BROWSER_SYNC_ENGINE_SYNC_PROCESS_STATE_H_
+#define CHROME_BROWSER_SYNC_ENGINE_SYNC_PROCESS_STATE_H_
+
+#include <map>
+#include <set>
+#include <utility> // for pair<>
+
+#include "base/atomicops.h"
+#include "base/basictypes.h"
+#include "base/port.h"
+#include "chrome/browser/sync/engine/net/server_connection_manager.h"
+#include "chrome/browser/sync/engine/syncer_types.h"
+#include "chrome/browser/sync/syncable/syncable_id.h"
+#include "testing/gtest/include/gtest/gtest_prod.h" // For FRIEND_TEST
+
+namespace browser_sync {
+
+class ConflictResolver;
+class ModelSafeWorker;
+
+class SyncProcessState {
+ FRIEND_TEST(SyncerSyncProcessState, MergeSetsTest);
+ FRIEND_TEST(SyncerTest, CopySyncProcessState);
+ public:
+ ~SyncProcessState();
+ SyncProcessState(
+ syncable::DirectoryManager* dirman,
+ PathString account_name,
+ ServerConnectionManager* connection_manager,
+ ConflictResolver* const resolver,
+ SyncerEventChannel* syncer_event_channel,
+ ModelSafeWorker* model_safe_worker);
+
+ // intentionally not 'explicit' b/c it's a copy ctor:
+ SyncProcessState(const SyncProcessState& counts);
+ SyncProcessState& operator=(const SyncProcessState& that);
+
+ PathString account_name() const { return account_name_; }
+
+ syncable::DirectoryManager* dirman() const { return dirman_; }
+
+ ServerConnectionManager* connection_manager()
+ const {
+ return connection_manager_;
+ }
+
+ ConflictResolver* resolver() const { return resolver_; }
+
+ ModelSafeWorker* model_safe_worker() { return model_safe_worker_; }
+
+ SyncerEventChannel* syncer_event_channel() const {
+ return syncer_event_channel_;
+ }
+
+ // Functions that deal with conflict set stuff
+ IdToConflictSetMap::const_iterator IdToConflictSetFind(
+ const syncable::Id& the_id) const {
+ return id_to_conflict_set_.find(the_id);
+ }
+
+ IdToConflictSetMap::const_iterator IdToConflictSetBegin() const {
+ return id_to_conflict_set_.begin();
+ }
+
+ IdToConflictSetMap::const_iterator IdToConflictSetEnd() const {
+ return id_to_conflict_set_.end();
+ }
+
+ IdToConflictSetMap::size_type IdToConflictSetSize() const {
+ return id_to_conflict_set_.size();
+ }
+
+ const ConflictSet* IdToConflictSetGet(const syncable::Id& the_id) {
+ return id_to_conflict_set_[the_id];
+ }
+
+ std::set<ConflictSet*>::const_iterator ConflictSetsBegin() const {
+ return conflict_sets_.begin();
+ }
+
+ std::set<ConflictSet*>::const_iterator ConflictSetsEnd() const {
+ return conflict_sets_.end();
+ }
+
+ std::set<ConflictSet*>::size_type ConflictSetsSize() const {
+ return conflict_sets_.size();
+ }
+
+ void MergeSets(const syncable::Id& set1, const syncable::Id& set2);
+
+ void CleanupSets();
+ // END conflict set functions
+
+ // item id set manipulation functions
+ bool HasConflictingItems() const {
+ return !conflicting_item_ids_.empty();
+ }
+
+ bool HasBlockedItems() const {
+ return !blocked_item_ids_.empty();
+ }
+
+ int ConflictingItemsSize() const {
+ return conflicting_item_ids_.size();
+ }
+
+ int BlockedItemsSize() const {
+ return blocked_item_ids_.size();
+ }
+
+ void AddConflictingItem(const syncable::Id& the_id) {
+ std::pair<std::set<syncable::Id>::iterator, bool> ret =
+ conflicting_item_ids_.insert(the_id);
+ UpdateDirty(ret.second);
+ }
+
+ void AddBlockedItem(const syncable::Id& the_id) {
+ std::pair<std::set<syncable::Id>::iterator, bool> ret =
+ blocked_item_ids_.insert(the_id);
+ UpdateDirty(ret.second);
+ }
+
+ void EraseConflictingItem(std::set<syncable::Id>::iterator it) {
+ UpdateDirty(true);
+ conflicting_item_ids_.erase(it);
+ }
+
+ void EraseBlockedItem(std::set<syncable::Id>::iterator it) {
+ UpdateDirty(true);
+ blocked_item_ids_.erase(it);
+ }
+
+ void EraseConflictingItem(const syncable::Id& the_id) {
+ int items_erased = conflicting_item_ids_.erase(the_id);
+ UpdateDirty(0 != items_erased);
+ }
+
+ void EraseBlockedItem(const syncable::Id& the_id) {
+ int items_erased = blocked_item_ids_.erase(the_id);
+ UpdateDirty(0 != items_erased);
+ }
+
+ std::set<syncable::Id>::iterator ConflictingItemsBegin() {
+ return conflicting_item_ids_.begin();
+ }
+
+ std::set<syncable::Id>::iterator BlockedItemsBegin() {
+ return blocked_item_ids_.begin();
+ }
+
+ std::set<syncable::Id>::iterator ConflictingItemsEnd() {
+ return conflicting_item_ids_.end();
+ }
+
+ std::set<syncable::Id>::iterator BlockedItemsEnd() {
+ return blocked_item_ids_.end();
+ }
+
+ void SetConflictingItems(const std::set<syncable::Id>& s) {
+ UpdateDirty(true);
+ conflicting_item_ids_ = s;
+ }
+
+ void SetBlockedItems(const std::set<syncable::Id>& s) {
+ UpdateDirty(true);
+ blocked_item_ids_ = s;
+ }
+ // END item id set manipulation functions
+
+ // Assorted other state info
+ int conflicting_updates() const { return conflicting_item_ids_.size(); }
+
+ int num_sync_cycles_;
+
+ // When we're over bandwidth quota, we don't update until past this time.
+ time_t silenced_until_;
+
+ // Info that is tracked purely for status reporting
+
+ // During inital sync these two members can be used to measure sync progress.
+ int64 current_sync_timestamp() const { return current_sync_timestamp_; }
+
+ int64 servers_latest_timestamp() const { return servers_latest_timestamp_; }
+
+ void set_current_sync_timestamp(const int64 val);
+
+ void set_servers_latest_timestamp(const int64 val);
+
+ bool invalid_store() const { return invalid_store_; }
+
+ void set_invalid_store(const bool val);
+
+ bool syncer_stuck() const { return syncer_stuck_; }
+
+ void set_syncer_stuck(const bool val);
+
+ bool syncing() const { return syncing_; }
+
+ void set_syncing(const bool val);
+
+ bool IsShareUsable() const;
+
+ int error_commits() const { return error_commits_; }
+
+ void set_error_commits(const int val);
+
+ int conflicting_commits() const { return conflicting_commits_; }
+
+ void set_conflicting_commits(const int val);
+
+ int stalled_commits() const { return stalled_commits_; }
+
+ void set_stalled_commits(const int val);
+
+ // WEIRD COUNTER manipulation functions
+ int consecutive_problem_get_updates() const {
+ return consecutive_problem_get_updates_;
+ }
+
+ void increment_consecutive_problem_get_updates();
+
+ void zero_consecutive_problem_get_updates();
+
+ int consecutive_problem_commits() const {
+ return consecutive_problem_commits_;
+ }
+
+ void increment_consecutive_problem_commits();
+
+ void zero_consecutive_problem_commits();
+
+ int consecutive_transient_error_commits() const {
+ return consecutive_transient_error_commits_;
+ }
+
+ void increment_consecutive_transient_error_commits_by(int value);
+
+ void zero_consecutive_transient_error_commits();
+
+ int consecutive_errors() const { return consecutive_errors_; }
+
+ void increment_consecutive_errors_by(int value);
+
+ void zero_consecutive_errors();
+
+ int successful_commits() const { return successful_commits_; }
+
+ void increment_successful_commits();
+
+ void zero_successful_commits();
+ // end WEIRD COUNTER manipulation functions
+
+ // Methods for managing error rate tracking
+ void TallyNewError();
+
+ void TallyBigNewError();
+
+ void ForgetOldError();
+
+ void CheckErrorRateTooHigh();
+
+ // Methods for tracking authentication state
+ void AuthFailed();
+ void AuthSucceeded();
+
+ // Returns true if this object has been modified since last SetClean() call
+ bool IsDirty() const { return dirty_; }
+
+ // Call to tell this status object that its new state has been seen
+ void SetClean() { dirty_ = false; }
+
+ // Returns true if auth status has been modified since last SetClean() call
+ bool IsAuthDirty() const { return auth_dirty_; }
+
+ // Call to tell this status object that its auth state has been seen
+ void SetAuthClean() { auth_dirty_ = false; }
+
+ private:
+ // for testing
+ SyncProcessState()
+ : account_name_(PSTR("")),
+ dirman_(NULL),
+ syncer_event_channel_(NULL),
+ connection_manager_(NULL),
+ model_safe_worker_(NULL),
+ resolver_(NULL),
+ syncer_stuck_(false),
+ num_sync_cycles_(0),
+ silenced_until_(0),
+ error_rate_(0),
+ current_sync_timestamp_(0),
+ servers_latest_timestamp_(0),
+ error_commits_(0),
+ stalled_commits_(0),
+ conflicting_commits_(0),
+ consecutive_problem_get_updates_(0),
+ consecutive_problem_commits_(0),
+ consecutive_transient_error_commits_(0),
+ consecutive_errors_(0),
+ successful_commits_(0),
+ dirty_(false),
+ auth_dirty_(false),
+ auth_failed_(false),
+ syncing_(false),
+ invalid_store_(false) {}
+
+ ServerConnectionManager *connection_manager_;
+ const PathString account_name_;
+ syncable::DirectoryManager* const dirman_;
+ ConflictResolver* const resolver_;
+ ModelSafeWorker* const model_safe_worker_;
+
+ // For sending notifications from sync commands out to observers of the
+ // Syncer.
+ SyncerEventChannel* syncer_event_channel_;
+
+ // TODO(sync): move away from sets if it makes more sense.
+ std::set<syncable::Id> conflicting_item_ids_;
+ std::set<syncable::Id> blocked_item_ids_;
+ std::map<syncable::Id, ConflictSet*> id_to_conflict_set_;
+ std::set<ConflictSet*> conflict_sets_;
+
+ // Status information, as opposed to state info that may also be exposed for
+ // status reporting purposes.
+ static const int ERROR_THRESHOLD = 500;
+ int error_rate_; // A EMA in the range [0,65536)
+ int64 current_sync_timestamp_; // During inital sync these two members
+ int64 servers_latest_timestamp_; // can be used to measure sync progress.
+
+ // There remains sync state updating in:
+ // CommitUnsyncedEntries
+ bool syncing_;
+
+ // True when we get such an INVALID_STORE error from the server.
+ bool invalid_store_;
+ // True iff we're stuck. User should contact support.
+ bool syncer_stuck_;
+ // counts of various commit return values.
+ int error_commits_;
+ int conflicting_commits_;
+ int stalled_commits_;
+
+ // WEIRD COUNTERS
+ // Two variables that track the # on consecutive problem requests.
+ // consecutive_problem_get_updates_ resets when we get any updates (not on
+ // pings) and increments whenever the request fails.
+ int consecutive_problem_get_updates_;
+ // consecutive_problem_commits_ resets whenever we commit any number of
+ // items and increments whenever all commits fail for any reason.
+ int consecutive_problem_commits_;
+ // number of commits hitting transient errors since the last successful
+ // commit.
+ int consecutive_transient_error_commits_;
+ // Incremented when get_updates fails, commit fails, and when
+ // hitting transient errors. When any of these succeed, this counter
+ // is reset.
+ // TODO(chron): Reduce number of weird counters we use.
+ int consecutive_errors_;
+ int successful_commits_;
+
+ bool dirty_;
+ bool auth_dirty_;
+ bool auth_failed_;
+
+ void UpdateDirty(bool new_info) { dirty_ |= new_info; }
+
+ void UpdateAuthDirty(bool new_info) { auth_dirty_ |= new_info; }
+};
+
+} // namespace browser_sync
+
+#endif // CHROME_BROWSER_SYNC_ENGINE_SYNC_PROCESS_STATE_H_