Home | History | Annotate | Download | only in sessions
      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