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 // A class representing an attempt to synchronize the local syncable data 6 // store with a sync server. A SyncSession instance is passed as a stateful 7 // bundle to and from various SyncerCommands with the goal of converging the 8 // client view of data with that of the server. The commands twiddle with 9 // session status in response to events and hiccups along the way, set and 10 // query session progress with regards to conflict resolution and applying 11 // server updates, and access the SyncSessionContext for the current session 12 // via SyncSession instances. 13 14 #ifndef CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSION_H_ 15 #define CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSION_H_ 16 #pragma once 17 18 #include <map> 19 #include <string> 20 #include <utility> 21 #include <vector> 22 23 #include "base/basictypes.h" 24 #include "base/memory/scoped_ptr.h" 25 #include "base/time.h" 26 #include "chrome/browser/sync/engine/model_safe_worker.h" 27 #include "chrome/browser/sync/sessions/ordered_commit_set.h" 28 #include "chrome/browser/sync/sessions/session_state.h" 29 #include "chrome/browser/sync/sessions/status_controller.h" 30 #include "chrome/browser/sync/sessions/sync_session_context.h" 31 #include "chrome/browser/sync/syncable/model_type.h" 32 #include "chrome/browser/sync/util/extensions_activity_monitor.h" 33 34 namespace syncable { 35 class WriteTransaction; 36 } 37 38 namespace browser_sync { 39 class ModelSafeWorker; 40 41 namespace sessions { 42 43 class SyncSession { 44 public: 45 // The Delegate services events that occur during the session requiring an 46 // explicit (and session-global) action, as opposed to events that are simply 47 // recorded in per-session state. 48 class Delegate { 49 public: 50 // The client was throttled and should cease-and-desist syncing activity 51 // until the specified time. 52 virtual void OnSilencedUntil(const base::TimeTicks& silenced_until) = 0; 53 54 // Silenced intervals can be out of phase with individual sessions, so the 55 // delegate is the only thing that can give an authoritative answer for 56 // "is syncing silenced right now". This shouldn't be necessary very often 57 // as the delegate ensures no session is started if syncing is silenced. 58 // ** Note ** This will return true if silencing commenced during this 59 // session and the interval has not yet elapsed, but the contract here is 60 // solely based on absolute time values. So, this cannot be used to infer 61 // that any given session _instance_ is silenced. An example of reasonable 62 // use is for UI reporting. 63 virtual bool IsSyncingCurrentlySilenced() = 0; 64 65 // The client has been instructed to change its short poll interval. 66 virtual void OnReceivedShortPollIntervalUpdate( 67 const base::TimeDelta& new_interval) = 0; 68 69 // The client has been instructed to change its long poll interval. 70 virtual void OnReceivedLongPollIntervalUpdate( 71 const base::TimeDelta& new_interval) = 0; 72 73 // The client needs to cease and desist syncing at once. This occurs when 74 // the Syncer detects that the backend store has fundamentally changed or 75 // is a different instance altogether (e.g. swapping from a test instance 76 // to production, or a global stop syncing operation has wiped the store). 77 virtual void OnShouldStopSyncingPermanently() = 0; 78 79 protected: 80 virtual ~Delegate() {} 81 }; 82 83 SyncSession(SyncSessionContext* context, 84 Delegate* delegate, 85 const SyncSourceInfo& source, 86 const ModelSafeRoutingInfo& routing_info, 87 const std::vector<ModelSafeWorker*>& workers); 88 ~SyncSession(); 89 90 // Builds a thread-safe and read-only copy of the current session state. 91 SyncSessionSnapshot TakeSnapshot() const; 92 93 // Returns true if this session contains data that should go through the sync 94 // engine again. 95 bool HasMoreToSync() const; 96 97 // Collects all state pertaining to how and why |s| originated and unions it 98 // with corresponding state in |this|, leaving |s| unchanged. Allows |this| 99 // to take on the responsibilities |s| had (e.g. certain data types) in the 100 // next SyncShare operation using |this|, rather than needed two separate 101 // sessions. 102 void Coalesce(const SyncSession& session); 103 104 // Should be called any time |this| is being re-used in a new call to 105 // SyncShare (e.g., HasMoreToSync returned true). 106 void ResetTransientState(); 107 108 SyncSessionContext* context() const { return context_; } 109 Delegate* delegate() const { return delegate_; } 110 syncable::WriteTransaction* write_transaction() { return write_transaction_; } 111 StatusController* status_controller() { return status_controller_.get(); } 112 113 const ExtensionsActivityMonitor::Records& extensions_activity() const { 114 return extensions_activity_; 115 } 116 ExtensionsActivityMonitor::Records* mutable_extensions_activity() { 117 return &extensions_activity_; 118 } 119 120 // Volatile reader for the source member of the sync session object. The 121 // value is set to the SYNC_CYCLE_CONTINUATION value to signal that it has 122 // been read. 123 SyncSourceInfo TestAndSetSource(); 124 125 const std::vector<ModelSafeWorker*>& workers() const { return workers_; } 126 const ModelSafeRoutingInfo& routing_info() const { return routing_info_; } 127 const SyncSourceInfo& source() const { return source_; } 128 129 private: 130 // Extend the encapsulation boundary to utilities for internal member 131 // assignments. This way, the scope of these actions is explicit, they can't 132 // be overridden, and assigning is always accompanied by unassigning. 133 friend class ScopedSetSessionWriteTransaction; 134 135 // The context for this session, guaranteed to outlive |this|. 136 SyncSessionContext* const context_; 137 138 // The source for initiating this sync session. 139 SyncSourceInfo source_; 140 141 // Information about extensions activity since the last successful commit. 142 ExtensionsActivityMonitor::Records extensions_activity_; 143 144 // Used to allow various steps to share a transaction. Can be NULL. 145 syncable::WriteTransaction* write_transaction_; 146 147 // The delegate for this session, must never be NULL. 148 Delegate* delegate_; 149 150 // Our controller for various status and error counters. 151 scoped_ptr<StatusController> status_controller_; 152 153 // The set of active ModelSafeWorkers for the duration of this session. 154 // This can change if this session is Coalesce()'d with another. 155 std::vector<ModelSafeWorker*> workers_; 156 157 // The routing info for the duration of this session, dictating which 158 // datatypes should be synced and which workers should be used when working 159 // on those datatypes. 160 ModelSafeRoutingInfo routing_info_; 161 162 DISALLOW_COPY_AND_ASSIGN(SyncSession); 163 }; 164 165 // Installs a WriteTransaction to a given session and later clears it when the 166 // utility falls out of scope. Transactions are not nestable, so it is an error 167 // to try and use one of these if the session already has a transaction. 168 class ScopedSetSessionWriteTransaction { 169 public: 170 ScopedSetSessionWriteTransaction(SyncSession* session, 171 syncable::WriteTransaction* trans) 172 : session_(session) { 173 DCHECK(!session_->write_transaction_); 174 session_->write_transaction_ = trans; 175 } 176 ~ScopedSetSessionWriteTransaction() { session_->write_transaction_ = NULL; } 177 178 private: 179 SyncSession* session_; 180 DISALLOW_COPY_AND_ASSIGN(ScopedSetSessionWriteTransaction); 181 }; 182 183 } // namespace sessions 184 } // namespace browser_sync 185 186 #endif // CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSION_H_ 187