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

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

Issue 6874018: make new syncer thread the default. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Send for CR. Created 9 years, 8 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
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // A class to run the syncer on a thread. 5 // A class to run the syncer on a thread.
6 // This is the default implementation of SyncerThread whose Stop implementation
7 // does not support a timeout, but is greatly simplified.
8 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ 6 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_
9 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ 7 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_
10 #pragma once 8 #pragma once
11 9
12 #include <list> 10 #include "base/callback.h"
13 #include <string> 11 #include "base/memory/linked_ptr.h"
tim (not reviewing) 2011/04/18 16:11:47 I'm assuming there were no changes to syncer_threa
lipalani1 2011/04/18 20:36:41 Yes it was a straight port. On 2011/04/18 16:11:47
14 #include <vector>
15
16 #include "base/basictypes.h"
17 #include "base/gtest_prod_util.h"
18 #include "base/memory/ref_counted.h"
19 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
20 #include "base/synchronization/condition_variable.h" 13 #include "base/observer_list.h"
14 #include "base/task.h"
21 #include "base/threading/thread.h" 15 #include "base/threading/thread.h"
22 #include "base/time.h" 16 #include "base/time.h"
23 #include "base/synchronization/waitable_event.h" 17 #include "base/timer.h"
24 #include "chrome/browser/sync/engine/syncer_types.h" 18 #include "chrome/browser/sync/engine/nudge_source.h"
19 #include "chrome/browser/sync/engine/polling_constants.h"
20 #include "chrome/browser/sync/engine/syncer.h"
21 #include "chrome/browser/sync/syncable/model_type_payload_map.h"
22 #include "chrome/browser/sync/engine/net/server_connection_manager.h"
25 #include "chrome/browser/sync/sessions/sync_session.h" 23 #include "chrome/browser/sync/sessions/sync_session.h"
26 #include "chrome/browser/sync/syncable/model_type.h" 24 #include "chrome/browser/sync/sessions/sync_session_context.h"
27 #include "chrome/browser/sync/syncable/model_type_payload_map.h"
28 #include "chrome/common/deprecated/event_sys-inl.h"
29
30 #if defined(OS_LINUX)
31 #include "chrome/browser/sync/engine/idle_query_linux.h"
32 #endif
33
34 class EventListenerHookup;
35 25
36 namespace browser_sync { 26 namespace browser_sync {
37 27
38 class ModelSafeWorker;
39 class ServerConnectionManager;
40 class Syncer;
41 class URLFactory;
42 struct ServerConnectionEvent; 28 struct ServerConnectionEvent;
43 29
44 class SyncerThread : public base::RefCountedThreadSafe<SyncerThread>, 30 class SyncerThread : public sessions::SyncSession::Delegate,
45 public sessions::SyncSession::Delegate { 31 public ServerConnectionEventListener {
46 FRIEND_TEST_ALL_PREFIXES(SyncerThreadTest, CalculateSyncWaitTime);
47 FRIEND_TEST_ALL_PREFIXES(SyncerThreadTest, CalculatePollingWaitTime);
48 FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, Polling);
49 FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, Nudge);
50 FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, NudgeWithDataTypes);
51 FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest,
52 NudgeWithDataTypesCoalesced);
53 FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, NudgeWithPayloads);
54 FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest,
55 NudgeWithPayloadsCoalesced);
56 FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, Throttling);
57 FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, AuthInvalid);
58 FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, Pause);
59 FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, StartWhenNotConnected);
60 FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, PauseWhenNotConnected);
61 FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, StopSyncPermanently);
62 friend class SyncerThreadWithSyncerTest;
63 friend class SyncerThreadFactory;
64 public: 32 public:
65 // Encapsulates the parameters that make up an interval on which the 33 enum Mode {
66 // syncer thread is sleeping. 34 // In this mode, the thread only performs configuration tasks. This is
35 // designed to make the case where we want to download updates for a
36 // specific type only, and not continue syncing until we are moved into
37 // normal mode.
38 CONFIGURATION_MODE,
39 // Resumes polling and allows nudges, drops configuration tasks. Runs
40 // through entire sync cycle.
41 NORMAL_MODE,
42 };
43
44 // Takes ownership of both |context| and |syncer|.
45 SyncerThread(sessions::SyncSessionContext* context, Syncer* syncer);
46 virtual ~SyncerThread();
47
48 typedef Callback0::Type ModeChangeCallback;
49
50 // Change the mode of operation.
51 // We don't use a lock when changing modes, so we won't cause currently
52 // scheduled jobs to adhere to the new mode. We could protect it, but it
53 // doesn't buy very much as a) a session could already be in progress and it
54 // will continue no matter what, b) the scheduled sessions already contain
55 // all their required state and won't be affected by potential change at
56 // higher levels (i.e. the registrar), and c) we service tasks FIFO, so once
57 // the mode changes all future jobs will be run against the updated mode.
58 // If supplied, |callback| will be invoked when the mode has been
59 // changed to |mode| *from the SyncerThread*, and not from the caller
60 // thread.
61 void Start(Mode mode, ModeChangeCallback* callback);
62
63 // Joins on the thread as soon as possible (currently running session
64 // completes).
65 void Stop();
66
67 // The meat and potatoes.
68 void ScheduleNudge(const base::TimeDelta& delay, NudgeSource source,
69 const syncable::ModelTypeBitSet& types,
70 const tracked_objects::Location& nudge_location);
71 void ScheduleNudgeWithPayloads(
72 const base::TimeDelta& delay, NudgeSource source,
73 const syncable::ModelTypePayloadMap& types_with_payloads,
74 const tracked_objects::Location& nudge_location);
75 void ScheduleConfig(const syncable::ModelTypeBitSet& types);
76 void ScheduleClearUserData();
77
78 // Change status of notifications in the SyncSessionContext.
79 void set_notifications_enabled(bool notifications_enabled);
80
81 // DDOS avoidance function. Calculates how long we should wait before trying
82 // again after a failed sync attempt, where the last delay was |base_delay|.
83 // TODO(tim): Look at URLRequestThrottlerEntryInterface.
84 static base::TimeDelta GetRecommendedDelay(const base::TimeDelta& base_delay);
85
86 // SyncSession::Delegate implementation.
87 virtual void OnSilencedUntil(const base::TimeTicks& silenced_until);
88 virtual bool IsSyncingCurrentlySilenced();
89 virtual void OnReceivedShortPollIntervalUpdate(
90 const base::TimeDelta& new_interval);
91 virtual void OnReceivedLongPollIntervalUpdate(
92 const base::TimeDelta& new_interval);
93 virtual void OnShouldStopSyncingPermanently();
94
95 // ServerConnectionEventListener implementation.
96 // TODO(tim): schedule a nudge when valid connection detected? in 1 minute?
97 virtual void OnServerConnectionEvent(const ServerConnectionEvent2& event);
98
99 private:
100 enum JobProcessDecision {
101 // Indicates we should continue with the current job.
102 CONTINUE,
103 // Indicates that we should save it to be processed later.
104 SAVE,
105 // Indicates we should drop this job.
106 DROP,
107 };
108
109 struct SyncSessionJob {
110 // An enum used to describe jobs for scheduling purposes.
111 enum SyncSessionJobPurpose {
112 // Our poll timer schedules POLL jobs periodically based on a server
113 // assigned poll interval.
114 POLL,
115 // A nudge task can come from a variety of components needing to force
116 // a sync. The source is inferable from |session.source()|.
117 NUDGE,
118 // The user invoked a function in the UI to clear their entire account
119 // and stop syncing (globally).
120 CLEAR_USER_DATA,
121 // Typically used for fetching updates for a subset of the enabled types
122 // during initial sync or reconfiguration. We don't run all steps of
123 // the sync cycle for these (e.g. CleanupDisabledTypes is skipped).
124 CONFIGURATION,
125 };
126 SyncSessionJob();
127 SyncSessionJob(SyncSessionJobPurpose purpose, base::TimeTicks start,
128 linked_ptr<sessions::SyncSession> session, bool is_canary_job,
129 const tracked_objects::Location& nudge_location);
130 ~SyncSessionJob();
131 SyncSessionJobPurpose purpose;
132 base::TimeTicks scheduled_start;
133 linked_ptr<sessions::SyncSession> session;
134 bool is_canary_job;
135
136 // This is the location the nudge came from. used for debugging purpose.
137 // In case of multiple nudges getting coalesced this stores the first nudge
138 // that came in.
139 tracked_objects::Location nudge_location;
140 };
141 friend class SyncerThread2Test;
142 friend class SyncerThread2WhiteboxTest;
143
144 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
145 DropNudgeWhileExponentialBackOff);
146 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, SaveNudge);
147 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, ContinueNudge);
148 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, DropPoll);
149 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, ContinuePoll);
150 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, ContinueConfiguration);
151 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
152 SaveConfigurationWhileThrottled);
153 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
154 SaveNudgeWhileThrottled);
155 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
156 ContinueClearUserDataUnderAllCircumstances);
157 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
158 ContinueCanaryJobConfig);
159 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
160 ContinueNudgeWhileExponentialBackOff);
161
162 // A component used to get time delays associated with exponential backoff.
163 // Encapsulated into a class to facilitate testing.
164 class DelayProvider {
165 public:
166 DelayProvider();
167 virtual base::TimeDelta GetDelay(const base::TimeDelta& last_delay);
168 virtual ~DelayProvider();
169 private:
170 DISALLOW_COPY_AND_ASSIGN(DelayProvider);
171 };
172
67 struct WaitInterval { 173 struct WaitInterval {
68 enum Mode { 174 enum Mode {
69 // A wait interval whose duration has not been affected by exponential
70 // backoff. The base case for exponential backoff falls in to this case
71 // (e.g when the exponent is 1). So far, we don't need a separate case.
72 // NORMAL intervals are not nudge-rate limited.
73 NORMAL,
74 // A wait interval whose duration has been affected by exponential 175 // A wait interval whose duration has been affected by exponential
75 // backoff. 176 // backoff.
76 // EXPONENTIAL_BACKOFF intervals are nudge-rate limited to 1 per interval. 177 // EXPONENTIAL_BACKOFF intervals are nudge-rate limited to 1 per interval.
77 EXPONENTIAL_BACKOFF, 178 EXPONENTIAL_BACKOFF,
78 // A server-initiated throttled interval. We do not allow any syncing 179 // A server-initiated throttled interval. We do not allow any syncing
79 // during such an interval. 180 // during such an interval.
80 THROTTLED, 181 THROTTLED,
81 }; 182 };
183 WaitInterval();
184 ~WaitInterval();
82 185
83 Mode mode; 186 Mode mode;
84 // This bool is set to true if we have observed a nudge during during this 187
188 // This bool is set to true if we have observed a nudge during this
85 // interval and mode == EXPONENTIAL_BACKOFF. 189 // interval and mode == EXPONENTIAL_BACKOFF.
86 bool had_nudge_during_backoff; 190 bool had_nudge;
87 base::TimeDelta poll_delta; // The wait duration until the next poll. 191 base::TimeDelta length;
192 base::OneShotTimer<SyncerThread> timer;
88 193
89 WaitInterval() : mode(NORMAL), had_nudge_during_backoff(false) { } 194 // Configure jobs are saved only when backing off or throttling. So we
195 // expose the pointer here.
196 scoped_ptr<SyncSessionJob> pending_configure_job;
197 WaitInterval(Mode mode, base::TimeDelta length);
90 }; 198 };
91 199
92 enum NudgeSource { 200 // Helper to assemble a job and post a delayed task to sync.
93 kUnknown = 0, 201 void ScheduleSyncSessionJob(
94 kNotification, 202 const base::TimeDelta& delay,
95 kLocal, 203 SyncSessionJob::SyncSessionJobPurpose purpose,
96 kContinuation, 204 sessions::SyncSession* session,
97 kClearPrivateData 205 const tracked_objects::Location& nudge_location);
98 };
99 // Server can overwrite these values via client commands.
100 // Standard short poll. This is used when XMPP is off.
101 static const int kDefaultShortPollIntervalSeconds;
102 // Long poll is used when XMPP is on.
103 static const int kDefaultLongPollIntervalSeconds;
104 // 30 minutes by default. If exponential backoff kicks in, this is the
105 // longest possible poll interval.
106 static const int kDefaultMaxPollIntervalMs;
107 // Maximum interval for exponential backoff.
108 static const int kMaxBackoffSeconds;
109 206
110 explicit SyncerThread(sessions::SyncSessionContext* context); 207 // Invoke the Syncer to perform a sync.
111 virtual ~SyncerThread(); 208 void DoSyncSessionJob(const SyncSessionJob& job);
112 209
113 virtual void WatchConnectionManager(ServerConnectionManager* conn_mgr); 210 // Called after the Syncer has performed the sync represented by |job|, to
211 // reset our state.
212 void FinishSyncSessionJob(const SyncSessionJob& job);
114 213
115 // Starts a syncer thread. 214 // Record important state that might be needed in future syncs, such as which
116 // Returns true if it creates a thread or if there's currently a thread 215 // data types may require cleanup.
117 // running and false otherwise. 216 void UpdateCarryoverSessionState(const SyncSessionJob& old_job);
118 virtual bool Start();
119 217
120 // Stop processing. |max_wait| doesn't do anything in this version. 218 // Helper to FinishSyncSessionJob to schedule the next sync operation.
121 virtual bool Stop(int max_wait); 219 void ScheduleNextSync(const SyncSessionJob& old_job);
122 220
123 // Request that the thread pauses. Returns false if the request can 221 // Helper to configure polling intervals. Used by Start and ScheduleNextSync.
124 // not be completed (e.g. the thread is not running). When the 222 void AdjustPolling(const SyncSessionJob* old_job);
125 // thread actually pauses, a SyncEngineEvent::PAUSED event notification
126 // will be sent to the relay channel.
127 virtual bool RequestPause();
128 223
129 // Request that the thread resumes from pause. Returns false if the 224 // Helper to ScheduleNextSync in case of consecutive sync errors.
130 // request can not be completed (e.g. the thread is not running or 225 void HandleConsecutiveContinuationError(const SyncSessionJob& old_job);
131 // is not currently paused). When the thread actually resumes, a
132 // SyncEngineEvent::RESUMED event notification will be sent to the relay
133 // channel.
134 virtual bool RequestResume();
135 226
136 // Nudges the syncer to sync with a delay specified. This API is for access 227 // Determines if it is legal to run |job| by checking current
137 // from the SyncerThread's controller and will cause a mutex lock. 228 // operational mode, backoff or throttling, freshness
138 virtual void NudgeSyncer(int milliseconds_from_now, NudgeSource source); 229 // (so we don't make redundant syncs), and connection.
230 bool ShouldRunJob(const SyncSessionJob& job);
139 231
140 // Same as |NudgeSyncer|, but supports tracking the datatypes that caused 232 // Decide whether we should CONTINUE, SAVE or DROP the job.
141 // the nudge to occur. 233 JobProcessDecision DecideOnJob(const SyncSessionJob& job);
142 virtual void NudgeSyncerWithDataTypes(
143 int milliseconds_from_now,
144 NudgeSource source,
145 const syncable::ModelTypeBitSet& model_types);
146 234
147 // Same as |NudgeSyncer|, but supports including a payload for passing on to 235 // Decide on whether to CONTINUE, SAVE or DROP the job when we are in
148 // the download updates command. Datatypes with payloads are also considered 236 // backoff mode.
149 // to have caused a nudged to occur and treated accordingly. 237 JobProcessDecision DecideWhileInWaitInterval(const SyncSessionJob& job);
150 virtual void NudgeSyncerWithPayloads(
151 int milliseconds_from_now,
152 NudgeSource source,
153 const syncable::ModelTypePayloadMap& model_types_with_payloads);
154 238
155 void SetNotificationsEnabled(bool notifications_enabled); 239 // Saves the job for future execution. Note: It drops all the poll jobs.
240 void SaveJob(const SyncSessionJob& job);
156 241
157 // Call this when a directory is opened 242 // Coalesces the current job with the pending nudge.
158 void CreateSyncer(const std::string& dirname); 243 void InitOrCoalescePendingJob(const SyncSessionJob& job);
159 244
160 // DDOS avoidance function. The argument and return value is in seconds 245 // 'Impl' here refers to real implementation of public functions, running on
161 static int GetRecommendedDelaySeconds(int base_delay_seconds); 246 // |thread_|.
247 void StartImpl(Mode mode, linked_ptr<ModeChangeCallback> callback);
248 void ScheduleNudgeImpl(
249 const base::TimeDelta& delay,
250 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source,
251 const syncable::ModelTypePayloadMap& types_with_payloads,
252 bool is_canary_job, const tracked_objects::Location& nudge_location);
253 void ScheduleConfigImpl(const ModelSafeRoutingInfo& routing_info,
254 const std::vector<ModelSafeWorker*>& workers,
255 const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source);
256 void ScheduleClearUserDataImpl();
162 257
163 protected: 258 // Returns true if the client is currently in exponential backoff.
164 virtual void ThreadMain(); 259 bool IsBackingOff() const;
165 void ThreadMainLoop();
166 260
167 virtual void SetConnected(bool connected); 261 // Helper to signal all listeners registered with |session_context_|.
168
169 virtual void SetSyncerPollingInterval(base::TimeDelta interval);
170 virtual void SetSyncerShortPollInterval(base::TimeDelta interval);
171
172 // Needed to emulate the behavior of pthread_create, which synchronously
173 // started the thread and set the value of thread_running_ to true.
174 // We can't quite match that because we asynchronously post the task,
175 // which opens a window for Stop to get called before the task actually
176 // makes it. To prevent this, we block Start() until we're sure it's ok.
177 base::WaitableEvent thread_main_started_;
178
179 // Handle of the running thread.
180 base::Thread thread_;
181
182 // Fields that are modified / accessed by multiple threads go in this struct
183 // for clarity and explicitness.
184 struct ProtectedFields {
185 ProtectedFields();
186 ~ProtectedFields();
187
188 // False when we want to stop the thread.
189 bool stop_syncer_thread_;
190
191 // True when a pause was requested.
192 bool pause_requested_;
193
194 // True when the thread is paused.
195 bool paused_;
196
197 Syncer* syncer_;
198
199 // State of the server connection.
200 bool connected_;
201
202 // kUnknown if there is no pending nudge. (Theoretically, there
203 // could be a pending nudge of type kUnknown, so it's better to
204 // check pending_nudge_time_.)
205 NudgeSource pending_nudge_source_;
206
207 // Map of all datatypes that are requesting a nudge. Can be union
208 // from multiple nudges that are coalesced. In addition, we
209 // optionally track a payload associated with each datatype (most recent
210 // payload overwrites old ones). These payloads are used by the download
211 // updates command and can contain datatype specific information the server
212 // might use.
213 syncable::ModelTypePayloadMap pending_nudge_types_;
214
215 // null iff there is no pending nudge.
216 base::TimeTicks pending_nudge_time_;
217
218 // The wait interval for to the current iteration of our main loop. This is
219 // only written to by the syncer thread, and since the only reader from a
220 // different thread (NudgeSync) is called at totally random times, we don't
221 // really need to access mutually exclusively as the data races that exist
222 // are intrinsic, but do so anyway and avoid using 'volatile'.
223 WaitInterval current_wait_interval_;
224 } vault_;
225
226 // Gets signaled whenever a thread outside of the syncer thread changes a
227 // protected field in the vault_.
228 base::ConditionVariable vault_field_changed_;
229
230 // Used to lock everything in |vault_|.
231 base::Lock lock_;
232
233 private:
234 // Threshold multipler for how long before user should be considered idle.
235 static const int kPollBackoffThresholdMultiplier = 10;
236
237 // SyncSession::Delegate implementation.
238 virtual void OnSilencedUntil(const base::TimeTicks& silenced_until);
239 virtual bool IsSyncingCurrentlySilenced();
240 virtual void OnReceivedShortPollIntervalUpdate(
241 const base::TimeDelta& new_interval);
242 virtual void OnReceivedLongPollIntervalUpdate(
243 const base::TimeDelta& new_interval);
244 virtual void OnShouldStopSyncingPermanently();
245
246 void HandleServerConnectionEvent(const ServerConnectionEvent& event);
247
248 // Collect all local state required for a sync and build a SyncSession out of
249 // it, reset state for the next time, and performs the sync cycle.
250 // See |GetAndResetNudgeSource| for details on what 'reset' means.
251 // |was_nudged| is set to true if the session returned is fulfilling a nudge.
252 // Returns once the session is finished (HasMoreToSync returns false). The
253 // caller owns the returned SyncSession.
254 sessions::SyncSession* SyncMain(Syncer* syncer,
255 bool was_throttled,
256 bool continue_sync_cycle,
257 bool* initial_sync_for_thread,
258 bool* was_nudged);
259
260 // Calculates the next sync wait time and exponential backoff state.
261 // last_poll_wait is the time duration of the previous polling timeout which
262 // was used. user_idle_milliseconds is updated by this method, and is a report
263 // of the full amount of time since the last period of activity for the user.
264 // The continue_sync_cycle parameter is used to determine whether or not we
265 // are calculating a polling wait time that is a continuation of an sync cycle
266 // which terminated while the syncer still had work to do. was_nudged is used
267 // in case of exponential backoff so we only allow one nudge per backoff
268 // interval.
269 WaitInterval CalculatePollingWaitTime(
270 int last_poll_wait, // in s
271 int* user_idle_milliseconds,
272 bool* continue_sync_cycle,
273 bool was_nudged);
274
275 // Helper to above function, considers effect of user idle time.
276 virtual int CalculateSyncWaitTime(int last_wait, int user_idle_ms);
277
278 // Resets the source tracking state to a clean slate and returns the current
279 // state in a SyncSourceInfo.
280 // The initial sync boolean is updated if read as a sentinel. The following
281 // two methods work in concert to achieve this goal.
282 // If |was_throttled| was true, this still discards elapsed nudges, but we
283 // treat the request as a periodic poll rather than a nudge from a source.
284 // Builds a SyncSourceInfo and returns whether a nudge occurred in the
285 // |was_nudged| parameter.
286 sessions::SyncSourceInfo GetAndResetNudgeSource(bool was_throttled,
287 bool continue_sync_cycle,
288 bool* initial_sync,
289 bool* was_nudged);
290
291 sessions::SyncSourceInfo MakeSyncSourceInfo(
292 bool nudged,
293 NudgeSource nudge_source,
294 const syncable::ModelTypePayloadMap& model_types_with_payloads,
295 bool* initial_sync);
296
297 int UserIdleTime();
298
299 void WaitUntilConnectedOrQuit();
300
301 // The thread will remain in this method until a resume is requested
302 // or shutdown is started.
303 void PauseUntilResumedOrQuit();
304
305 void EnterPausedState();
306
307 void ExitPausedState();
308
309 // For unit tests only.
310 virtual void DisableIdleDetection();
311
312 // This sets all conditions for syncer thread termination but does not
313 // actually join threads. It is expected that Stop will be called at some
314 // time after to fully stop and clean up.
315 void RequestSyncerExitAndSetThreadStopConditions();
316
317 void Notify(SyncEngineEvent::EventCause cause); 262 void Notify(SyncEngineEvent::EventCause cause);
318 263
319 scoped_ptr<EventListenerHookup> conn_mgr_hookup_; 264 // Callback to change backoff state.
265 void DoCanaryJob();
266 void Unthrottle();
267
268 // Executes the pending job. Called whenever an event occurs that may
269 // change conditions permitting a job to run. Like when network connection is
270 // re-established, mode changes etc.
271 void DoPendingJobIfPossible(bool is_canary_job);
272
273 // The pointer is owned by the caller.
274 browser_sync::sessions::SyncSession* CreateSyncSession(
275 const browser_sync::sessions::SyncSourceInfo& info);
276
277 // Creates a session for a poll and performs the sync.
278 void PollTimerCallback();
279
280 // Assign |start| and |end| to appropriate SyncerStep values for the
281 // specified |purpose|.
282 void SetSyncerStepsForPurpose(SyncSessionJob::SyncSessionJobPurpose purpose,
283 SyncerStep* start,
284 SyncerStep* end);
285
286 // Initializes the hookup between the ServerConnectionManager and us.
287 void WatchConnectionManager();
288
289 // Used to update |server_connection_ok_|, see below.
290 void CheckServerConnectionManagerStatus(
291 HttpResponse::ServerConnectionCode code);
292
293 // Called once the first time thread_ is started to broadcast an initial
294 // session snapshot containing data like initial_sync_ended. Important when
295 // the client starts up and does not need to perform an initial sync.
296 void SendInitialSnapshot();
297
298 base::Thread thread_;
320 299
321 // Modifiable versions of kDefaultLongPollIntervalSeconds which can be 300 // Modifiable versions of kDefaultLongPollIntervalSeconds which can be
322 // updated by the server. 301 // updated by the server.
323 int syncer_short_poll_interval_seconds_; 302 base::TimeDelta syncer_short_poll_interval_seconds_;
324 int syncer_long_poll_interval_seconds_; 303 base::TimeDelta syncer_long_poll_interval_seconds_;
325 304
326 // The time we wait between polls in seconds. This is used as lower bound on 305 // Periodic timer for polling. See AdjustPolling.
327 // our wait time. Updated once per loop from the command line flag. 306 base::RepeatingTimer<SyncerThread> poll_timer_;
328 int syncer_polling_interval_;
329 307
330 // The upper bound on the nominal wait between polls in seconds. Note that 308 // The mode of operation. We don't use a lock, see Start(...) comment.
331 // this bounds the "nominal" poll interval, while the the actual interval 309 Mode mode_;
332 // also takes previous failures into account.
333 int syncer_max_interval_;
334 310
335 // This causes syncer to start syncing ASAP. If the rate of requests is too 311 // TODO(tim): Bug 26339. This needs to track more than just time I think,
336 // high the request will be silently dropped. mutex_ should be held when 312 // since the nudges could be for different types. Current impl doesn't care.
337 // this is called. 313 base::TimeTicks last_sync_session_end_time_;
338 void NudgeSyncImpl(
339 int milliseconds_from_now,
340 NudgeSource source,
341 const syncable::ModelTypePayloadMap& model_types_with_payloads);
342 314
343 #if defined(OS_LINUX) 315 // Have we observed a valid server connection?
344 // On Linux, we need this information in order to query idle time. 316 bool server_connection_ok_;
345 scoped_ptr<IdleQueryLinux> idle_query_; 317
346 #endif 318 // Tracks in-flight nudges so we can coalesce.
319 scoped_ptr<SyncSessionJob> pending_nudge_;
320
321 // Current wait state. Null if we're not in backoff and not throttled.
322 scoped_ptr<WaitInterval> wait_interval_;
323
324 scoped_ptr<DelayProvider> delay_provider_;
325
326 // Invoked to run through the sync cycle.
327 scoped_ptr<Syncer> syncer_;
347 328
348 scoped_ptr<sessions::SyncSessionContext> session_context_; 329 scoped_ptr<sessions::SyncSessionContext> session_context_;
349 330
350 // Set whenever the server instructs us to stop sending it requests until
351 // a specified time, and reset for each call to SyncShare. (Note that the
352 // WaitInterval::THROTTLED contract is such that we don't call SyncShare at
353 // all until the "silenced until" embargo expires.)
354 base::TimeTicks silenced_until_;
355
356 // Useful for unit tests
357 bool disable_idle_detection_;
358
359 DISALLOW_COPY_AND_ASSIGN(SyncerThread); 331 DISALLOW_COPY_AND_ASSIGN(SyncerThread);
360 }; 332 };
361 333
334
362 } // namespace browser_sync 335 } // namespace browser_sync
363 336
337 // The SyncerThread manages its own internal thread and thus outlives it. We
338 // don't need refcounting for posting tasks to this internal thread.
339 DISABLE_RUNNABLE_METHOD_REFCOUNT(browser_sync::SyncerThread);
340
364 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ 341 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698