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 34namespace syncable { 35class WriteTransaction; 36} 37 38namespace browser_sync { 39class ModelSafeWorker; 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 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. 168class 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