Home | History | Annotate | Download | only in engine
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_H_
      6 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_H_
      7 #pragma once
      8 
      9 #include <utility>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/callback.h"
     14 #include "base/gtest_prod_util.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/synchronization/lock.h"
     17 #include "chrome/browser/sync/engine/conflict_resolver.h"
     18 #include "chrome/browser/sync/engine/syncer_types.h"
     19 #include "chrome/browser/sync/engine/syncproto.h"
     20 #include "chrome/browser/sync/sessions/sync_session.h"
     21 #include "chrome/browser/sync/syncable/directory_event.h"
     22 #include "chrome/browser/sync/syncable/model_type.h"
     23 #include "chrome/browser/sync/util/extensions_activity_monitor.h"
     24 #include "chrome/common/deprecated/event_sys.h"
     25 #include "chrome/common/deprecated/event_sys-inl.h"
     26 
     27 namespace syncable {
     28 class Directory;
     29 class DirectoryManager;
     30 class Entry;
     31 class Id;
     32 class MutableEntry;
     33 class WriteTransaction;
     34 }  // namespace syncable
     35 
     36 namespace browser_sync {
     37 
     38 class ModelSafeWorker;
     39 class ServerConnectionManager;
     40 class SyncProcessState;
     41 class URLFactory;
     42 struct HttpResponse;
     43 
     44 enum SyncerStep {
     45   SYNCER_BEGIN,
     46   CLEANUP_DISABLED_TYPES,
     47   DOWNLOAD_UPDATES,
     48   PROCESS_CLIENT_COMMAND,
     49   VERIFY_UPDATES,
     50   PROCESS_UPDATES,
     51   STORE_TIMESTAMPS,
     52   APPLY_UPDATES,
     53   BUILD_COMMIT_REQUEST,
     54   POST_COMMIT_MESSAGE,
     55   PROCESS_COMMIT_RESPONSE,
     56   BUILD_AND_PROCESS_CONFLICT_SETS,
     57   RESOLVE_CONFLICTS,
     58   APPLY_UPDATES_TO_RESOLVE_CONFLICTS,
     59   CLEAR_PRIVATE_DATA,  // TODO(tim): Rename 'private' to 'user'.
     60   SYNCER_END
     61 };
     62 
     63 // A Syncer provides a control interface for driving the individual steps
     64 // of the sync cycle.  Each cycle (hopefully) moves the client into closer
     65 // synchronization with the server.  The individual steps are modeled
     66 // as SyncerCommands, and the ordering of the steps is expressed using
     67 // the SyncerStep enum.
     68 //
     69 // A Syncer instance expects to run on a dedicated thread.  Calls
     70 // to SyncShare() may take an unbounded amount of time, as SyncerCommands
     71 // may block on network i/o, on lock contention, or on tasks posted to
     72 // other threads.
     73 class Syncer {
     74  public:
     75   typedef std::vector<int64> UnsyncedMetaHandles;
     76 
     77   // The constructor may be called from a thread that is not the Syncer's
     78   // dedicated thread, to allow some flexibility in the setup.
     79   Syncer();
     80   virtual ~Syncer();
     81 
     82   // Called by other threads to tell the syncer to stop what it's doing
     83   // and return early from SyncShare, if possible.
     84   bool ExitRequested();
     85   void RequestEarlyExit();
     86 
     87   // TODO(tim): Deprecated.
     88   // Cause one sync cycle to occur.  Like a good parent, it is the caller's
     89   // responsibility to clean up after the syncer when it finishes a sync share
     90   // operation and honor server mandated throttles.
     91   virtual void SyncShare(sessions::SyncSession* session);
     92 
     93   // Like SyncShare() above, but |first_step| and |last_step| are provided to
     94   // perform a partial sync cycle, stopping after |last_step| is performed.
     95   virtual void SyncShare(sessions::SyncSession* session,
     96                          SyncerStep first_step,
     97                          SyncerStep last_step);
     98 
     99  private:
    100   // Implements the PROCESS_CLIENT_COMMAND syncer step.
    101   void ProcessClientCommand(sessions::SyncSession* session);
    102 
    103   bool early_exit_requested_;
    104   base::Lock early_exit_requested_lock_;
    105 
    106   ConflictResolver resolver_;
    107 
    108   // A callback hook used in unittests to simulate changes between conflict set
    109   // building and conflict resolution.
    110   Callback0::Type* pre_conflict_resolution_closure_;
    111 
    112   friend class SyncerTest;
    113   FRIEND_TEST_ALL_PREFIXES(SyncerTest, NameClashWithResolver);
    114   FRIEND_TEST_ALL_PREFIXES(SyncerTest, IllegalAndLegalUpdates);
    115   FRIEND_TEST_ALL_PREFIXES(SusanDeletingTest,
    116                            NewServerItemInAFolderHierarchyWeHaveDeleted3);
    117   FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestCommitListOrderingAndNewParent);
    118   FRIEND_TEST_ALL_PREFIXES(SyncerTest,
    119                            TestCommitListOrderingAndNewParentAndChild);
    120   FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestCommitListOrderingCounterexample);
    121   FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestCommitListOrderingWithNesting);
    122   FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestCommitListOrderingWithNewItems);
    123   FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestGetUnsyncedAndSimpleCommit);
    124   FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestPurgeWhileUnsynced);
    125   FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestPurgeWhileUnapplied);
    126   FRIEND_TEST_ALL_PREFIXES(SyncerTest, UnappliedUpdateDuringCommit);
    127   FRIEND_TEST_ALL_PREFIXES(SyncerTest, DeletingEntryInFolder);
    128   FRIEND_TEST_ALL_PREFIXES(SyncerTest,
    129                            LongChangelistCreatesFakeOrphanedEntries);
    130   FRIEND_TEST_ALL_PREFIXES(SyncerTest, QuicklyMergeDualCreatedHierarchy);
    131   FRIEND_TEST_ALL_PREFIXES(SyncerTest, LongChangelistWithApplicationConflict);
    132   FRIEND_TEST_ALL_PREFIXES(SyncerTest, DeletingEntryWithLocalEdits);
    133   FRIEND_TEST_ALL_PREFIXES(EntryCreatedInNewFolderTest,
    134                            EntryCreatedInNewFolderMidSync);
    135 
    136   DISALLOW_COPY_AND_ASSIGN(Syncer);
    137 };
    138 
    139 // Inline utility functions.
    140 
    141 // Given iterator ranges from two collections sorted according to a common
    142 // strict weak ordering, return true if the two ranges contain any common
    143 // items, and false if they do not. This function is in this header so that it
    144 // can be tested.
    145 template <class Iterator1, class Iterator2>
    146 bool SortedCollectionsIntersect(Iterator1 begin1, Iterator1 end1,
    147                                 Iterator2 begin2, Iterator2 end2) {
    148   Iterator1 i1 = begin1;
    149   Iterator2 i2 = begin2;
    150   while (i1 != end1 && i2 != end2) {
    151     if (*i1 == *i2)
    152       return true;
    153     if (*i1 > *i2)
    154       ++i2;
    155     else
    156       ++i1;
    157   }
    158   return false;
    159 }
    160 // Utility function declarations.
    161 void CopyServerFields(syncable::Entry* src, syncable::MutableEntry* dest);
    162 void ClearServerData(syncable::MutableEntry* entry);
    163 
    164 }  // namespace browser_sync
    165 
    166 #endif  // CHROME_BROWSER_SYNC_ENGINE_SYNCER_H_
    167 
    168