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

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

Powered by Google App Engine
This is Rietveld 408576698