Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: chrome/browser/sync/engine/syncer_thread2.h

Issue 5939006: sync: beginnings of MessageLoop based SyncerThread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix specialization specialization Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 to run the syncer on a thread.
6 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD2_H_
7 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD2_H_
8 #pragma once
9
10 #include "base/linked_ptr.h"
11 #include "base/observer_list.h"
12 #include "base/task.h"
13 #include "base/threading/thread.h"
14 #include "base/time.h"
15 #include "base/timer.h"
16 #include "chrome/browser/sync/engine/nudge_source.h"
17 #include "chrome/browser/sync/engine/polling_constants.h"
18 #include "chrome/browser/sync/sessions/sync_session.h"
19 #include "chrome/browser/sync/sessions/sync_session_context.h"
20
21 namespace browser_sync {
22
23 struct ServerConnectionEvent;
24 class Syncer;
25
26 namespace s3 {
27
28 class SyncerThread : public sessions::SyncSession::Delegate {
29 public:
30 enum Mode {
31 // In this mode, the thread only performs configuration tasks. This is
32 // designed to make the case where we want to download updates for a
33 // specific type only, and not continue syncing until we are moved into
34 // normal mode.
35 CONFIGURATION_MODE,
36 // Resumes polling and allows nudges, drops configuration tasks. Runs
37 // through entire sync cycle.
38 NORMAL_MODE,
39 };
40
41 // Takes ownership of both |context| and |syncer|.
42 SyncerThread(sessions::SyncSessionContext* context, Syncer* syncer);
43 virtual ~SyncerThread();
44
45 // Change the mode of operation.
46 // We don't use a lock when changing modes, so we won't cause currently
47 // scheduled jobs to adhere to the new mode. We could protect it, but it
48 // doesn't buy very much as a) a session could already be in progress and it
49 // will continue no matter what, b) the scheduled sessions already contain
50 // all their required state and won't be affected by potential change at
51 // higher levels (i.e. the registrar), and c) we service tasks FIFO, so once
52 // the mode changes all future jobs will be run against the updated mode.
53 void Start(Mode mode);
54
55 // Joins on the thread as soon as possible (currently running session
56 // completes).
57 void Stop();
58
59 // The meat and potatoes.
60 void ScheduleNudge(const base::TimeDelta& delay, NudgeSource source,
61 const syncable::ModelTypeBitSet& types);
62 void ScheduleConfig(const base::TimeDelta& delay,
63 const syncable::ModelTypeBitSet& types);
64
65 // Change status of notifications in the SyncSessionContext.
66 void set_notifications_enabled(bool notifications_enabled);
67
68 // DDOS avoidance function. Calculates how long we should wait before trying
69 // again after a failed sync attempt, where the last delay was |base_delay|.
70 // TODO(tim): Look at URLRequestThrottlerEntryInterface.
71 static base::TimeDelta GetRecommendedDelay(const base::TimeDelta& base_delay);
72
73 // SyncSession::Delegate implementation.
74 virtual void OnSilencedUntil(const base::TimeTicks& silenced_until);
75 virtual bool IsSyncingCurrentlySilenced();
76 virtual void OnReceivedShortPollIntervalUpdate(
77 const base::TimeDelta& new_interval);
78 virtual void OnReceivedLongPollIntervalUpdate(
79 const base::TimeDelta& new_interval);
80 virtual void OnShouldStopSyncingPermanently();
81
82 private:
83 friend class SyncerThread2Test;
84
85 // State pertaining to exponential backoff or throttling periods.
86 struct WaitInterval {
87 enum Mode {
88 // A wait interval whose duration has been affected by exponential
89 // backoff.
90 // EXPONENTIAL_BACKOFF intervals are nudge-rate limited to 1 per interval.
91 EXPONENTIAL_BACKOFF,
92 // A server-initiated throttled interval. We do not allow any syncing
93 // during such an interval.
94 THROTTLED,
95 };
96 Mode mode;
97
98 // This bool is set to true if we have observed a nudge during this
99 // interval and mode == EXPONENTIAL_BACKOFF.
100 bool had_nudge;
101 base::TimeDelta length;
102 base::OneShotTimer<SyncerThread> timer;
103 WaitInterval(Mode mode, base::TimeDelta length);
104 };
105
106 // Internal state for every sync task that is scheduled.
107 struct SyncSessionJob {
108 // An enum used to describe jobs for scheduling purposes.
109 enum Purpose {
110 // Our poll timer schedules POLL jobs periodically based on a server
111 // assigned poll interval.
112 POLL,
113 // A nudge task can come from a variety of components needing to force
114 // a sync. The source is inferable from |session.source()|.
115 NUDGE,
116 // Typically used for fetching updates for a subset of the enabled types
117 // during initial sync or reconfiguration. We don't run all steps of
118 // the sync cycle for these (e.g. CleanupDisabledTypes is skipped).
119 CONFIGURATION,
120 };
121
122 Purpose purpose;
123 base::TimeTicks scheduled_start;
124 linked_ptr<sessions::SyncSession> session;
125 };
126
127 // A component used to get time delays associated with exponential backoff.
128 // Encapsulated into a class to facilitate testing.
129 class DelayProvider {
130 public:
131 DelayProvider();
132 virtual base::TimeDelta GetDelay(const base::TimeDelta& last_delay);
133 virtual ~DelayProvider();
134 private:
135 DISALLOW_COPY_AND_ASSIGN(DelayProvider);
136 };
137
138 // Helper to assemble a job and post a delayed task to sync.
139 void ScheduleSyncSessionJob(const base::TimeDelta& delay,
140 SyncSessionJob::Purpose purpose,
141 sessions::SyncSession* session);
142
143 // Invoke the Syncer to perform a sync.
144 void DoSyncSessionJob(const SyncSessionJob& job);
145
146 // Called after the Syncer has performed the sync represented by |job|, to
147 // reset our state.
148 void FinishSyncSessionJob(const SyncSessionJob& job);
149
150 // Helper to FinishSyncSessionJob to schedule the next sync operation.
151 void ScheduleNextSync(const SyncSessionJob& old_job);
152
153 // Helper to configure polling intervals. Used by Start and ScheduleNextSync.
154 void AdjustPolling(const SyncSessionJob* old_job);
155
156 // Helper to ScheduleNextSync in case of consecutive sync errors.
157 void HandleConsecutiveContinuationError(const SyncSessionJob& old_job);
158
159 // Determines if it is legal to run a sync job for |purpose| at
160 // |scheduled_start|. This checks current operational mode, backoff or
161 // throttling, freshness (so we don't make redundant syncs), and connection.
162 bool ShouldRunJob(SyncSessionJob::Purpose purpose,
163 const base::TimeTicks& scheduled_start);
164
165 // 'Impl' here refers to real implementation of public functions, running on
166 // |thread_|.
167 void StartImpl(Mode mode);
168 void ScheduleNudgeImpl(const base::TimeDelta& delay,
169 NudgeSource source,
170 const syncable::ModelTypeBitSet& model_types);
171 void ScheduleConfigImpl(const base::TimeDelta& delay,
172 const ModelSafeRoutingInfo& routing_info,
173 const std::vector<ModelSafeWorker*>& workers);
174
175 // Returns true if the client is currently in exponential backoff.
176 bool IsBackingOff() const;
177
178 // Helper to signal all listeners registered with |session_context_|.
179 void Notify(SyncEngineEvent::EventCause cause);
180
181 // ServerConnectionEventListener implementation.
182 // TODO(tim): schedule a nudge when valid connection detected? in 1 minute?
183 virtual void OnServerConnectionEvent(const ServerConnectionEvent& event);
184
185 // Callback to change backoff state.
186 void DoCanaryJob();
187 void Unthrottle();
188
189 // Creates a session for a poll and performs the sync.
190 void PollTimerCallback();
191
192 base::Thread thread_;
193
194 // Modifiable versions of kDefaultLongPollIntervalSeconds which can be
195 // updated by the server.
196 base::TimeDelta syncer_short_poll_interval_seconds_;
197 base::TimeDelta syncer_long_poll_interval_seconds_;
198
199 // Periodic timer for polling. See AdjustPolling.
200 base::RepeatingTimer<SyncerThread> poll_timer_;
201
202 // The mode of operation. We don't use a lock, see Start(...) comment.
203 Mode mode_;
204
205 // TODO(tim): Bug 26339. This needs to track more than just time I think,
206 // since the nudges could be for different types. Current impl doesn't care.
207 base::TimeTicks last_sync_session_end_time_;
208
209 // Have we observed a valid server connection?
210 bool server_connection_ok_;
211
212 // Tracks in-flight nudges so we can coalesce.
213 scoped_ptr<SyncSessionJob> pending_nudge_;
214
215 // Current wait state. Null if we're not in backoff and not throttled.
216 scoped_ptr<WaitInterval> wait_interval_;
217
218 scoped_ptr<DelayProvider> delay_provider_;
219
220 // Invoked to run through the sync cycle.
221 scoped_ptr<Syncer> syncer_;
akalin 2011/01/26 10:49:19 need include for scoped_ptr
222
223 scoped_ptr<sessions::SyncSessionContext> session_context_;
224
225 DISALLOW_COPY_AND_ASSIGN(SyncerThread);
226 };
227
228 } // namespace s3
229
230 } // namespace browser_sync
231
232 // The SyncerThread manages its own internal thread and thus outlives it. We
233 // don't need refcounting for posting tasks to this internal thread.
234 DISABLE_RUNNABLE_METHOD_REFCOUNT(browser_sync::s3::SyncerThread);
235
236 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD2_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698