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