Chromium Code Reviews| Index: chrome/browser/sync/engine/sync_process_state.h |
| =================================================================== |
| --- chrome/browser/sync/engine/sync_process_state.h (revision 0) |
| +++ chrome/browser/sync/engine/sync_process_state.h (revision 0) |
| @@ -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 { |
|
idana
2009/09/10 05:44:37
'const' should be moved to the previous line.
|
| + 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_; |
|
idana
2009/09/10 05:44:37
"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_ |
| Property changes on: chrome\browser\sync\engine\sync_process_state.h |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + LF |