sync_session.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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// 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 SYNC_SESSIONS_SYNC_SESSION_H_ 15#define SYNC_SESSIONS_SYNC_SESSION_H_ 16 17#include <map> 18#include <set> 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 "sync/internal_api/public/base/model_type.h" 27#include "sync/internal_api/public/engine/model_safe_worker.h" 28#include "sync/internal_api/public/sessions/sync_session_snapshot.h" 29#include "sync/sessions/ordered_commit_set.h" 30#include "sync/sessions/status_controller.h" 31#include "sync/sessions/sync_session_context.h" 32#include "sync/util/extensions_activity_monitor.h" 33 34namespace syncer { 35class ModelSafeWorker; 36 37namespace syncable { 38class WriteTransaction; 39} 40 41namespace sessions { 42 43class 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 has been instructed to change its sessions commit 74 // delay. 75 virtual void OnReceivedSessionsCommitDelay( 76 const base::TimeDelta& new_delay) = 0; 77 78 // The client needs to cease and desist syncing at once. This occurs when 79 // the Syncer detects that the backend store has fundamentally changed or 80 // is a different instance altogether (e.g. swapping from a test instance 81 // to production, or a global stop syncing operation has wiped the store). 82 // TODO(lipalani) : Replace this function with the one below. This function 83 // stops the current sync cycle and purges the client. In the new model 84 // the former would be done by the |SyncProtocolError| and 85 // the latter(which is an action) would be done in ProfileSyncService 86 // along with the rest of the actions. 87 virtual void OnShouldStopSyncingPermanently() = 0; 88 89 // Called for the syncer to respond to the error sent by the server. 90 virtual void OnSyncProtocolError( 91 const sessions::SyncSessionSnapshot& snapshot) = 0; 92 93 protected: 94 virtual ~Delegate() {} 95 }; 96 97 SyncSession(SyncSessionContext* context, 98 Delegate* delegate, 99 const SyncSourceInfo& source, 100 const ModelSafeRoutingInfo& routing_info, 101 const std::vector<ModelSafeWorker*>& workers); 102 ~SyncSession(); 103 104 // Builds a thread-safe and read-only copy of the current session state. 105 SyncSessionSnapshot TakeSnapshot() const; 106 107 // Builds and sends a snapshot to the session context's listeners. 108 void SendEventNotification(SyncEngineEvent::EventCause cause); 109 110 // Returns true if we reached the server. Note that "reaching the server" 111 // here means that from an HTTP perspective, we succeeded (HTTP 200). The 112 // server **MAY** have returned a sync protocol error. 113 // See SERVER_RETURN_* in the SyncerError enum for values. 114 bool DidReachServer() const; 115 116 // Collects all state pertaining to how and why |s| originated and unions it 117 // with corresponding state in |this|, leaving |s| unchanged. Allows |this| 118 // to take on the responsibilities |s| had (e.g. certain data types) in the 119 // next SyncShare operation using |this|, rather than needed two separate 120 // sessions. 121 void Coalesce(const SyncSession& session); 122 123 // Compares the routing_info_, workers and payload map with those passed in. 124 // Purges types from the above 3 which are not present in latest. Useful 125 // to update the sync session when the user has disabled some types from 126 // syncing. 127 void RebaseRoutingInfoWithLatest( 128 const ModelSafeRoutingInfo& routing_info, 129 const std::vector<ModelSafeWorker*>& workers); 130 131 // TODO(akalin): Split this into context() and mutable_context(). 132 SyncSessionContext* context() const { return context_; } 133 Delegate* delegate() const { return delegate_; } 134 syncable::WriteTransaction* write_transaction() { return write_transaction_; } 135 const StatusController& status_controller() const { 136 return *status_controller_.get(); 137 } 138 StatusController* mutable_status_controller() { 139 return status_controller_.get(); 140 } 141 142 const ExtensionsActivityMonitor::Records& extensions_activity() const { 143 return extensions_activity_; 144 } 145 ExtensionsActivityMonitor::Records* mutable_extensions_activity() { 146 return &extensions_activity_; 147 } 148 149 const std::vector<ModelSafeWorker*>& workers() const { return workers_; } 150 const ModelSafeRoutingInfo& routing_info() const { return routing_info_; } 151 const SyncSourceInfo& source() const { return source_; } 152 153 // Returns the set of groups which have enabled types. 154 const std::set<ModelSafeGroup>& GetEnabledGroups() const; 155 156 private: 157 // Extend the encapsulation boundary to utilities for internal member 158 // assignments. This way, the scope of these actions is explicit, they can't 159 // be overridden, and assigning is always accompanied by unassigning. 160 friend class ScopedSetSessionWriteTransaction; 161 162 // The context for this session, guaranteed to outlive |this|. 163 SyncSessionContext* const context_; 164 165 // The source for initiating this sync session. 166 SyncSourceInfo source_; 167 168 // Information about extensions activity since the last successful commit. 169 ExtensionsActivityMonitor::Records extensions_activity_; 170 171 // Used to allow various steps to share a transaction. Can be NULL. 172 syncable::WriteTransaction* write_transaction_; 173 174 // The delegate for this session, must never be NULL. 175 Delegate* const delegate_; 176 177 // Our controller for various status and error counters. 178 scoped_ptr<StatusController> status_controller_; 179 180 // The set of active ModelSafeWorkers for the duration of this session. 181 // This can change if this session is Coalesce()'d with another. 182 std::vector<ModelSafeWorker*> workers_; 183 184 // The routing info for the duration of this session, dictating which 185 // datatypes should be synced and which workers should be used when working 186 // on those datatypes. 187 ModelSafeRoutingInfo routing_info_; 188 189 // The set of groups with enabled types. Computed from 190 // |routing_info_|. 191 std::set<ModelSafeGroup> enabled_groups_; 192 193 DISALLOW_COPY_AND_ASSIGN(SyncSession); 194}; 195 196// Installs a WriteTransaction to a given session and later clears it when the 197// utility falls out of scope. Transactions are not nestable, so it is an error 198// to try and use one of these if the session already has a transaction. 199class ScopedSetSessionWriteTransaction { 200 public: 201 ScopedSetSessionWriteTransaction(SyncSession* session, 202 syncable::WriteTransaction* trans) 203 : session_(session) { 204 DCHECK(!session_->write_transaction_); 205 session_->write_transaction_ = trans; 206 } 207 ~ScopedSetSessionWriteTransaction() { session_->write_transaction_ = NULL; } 208 209 private: 210 SyncSession* session_; 211 DISALLOW_COPY_AND_ASSIGN(ScopedSetSessionWriteTransaction); 212}; 213 214} // namespace sessions 215} // namespace syncer 216 217#endif // SYNC_SESSIONS_SYNC_SESSION_H_ 218