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

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: revert syncer_thread.cc 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 it modes won't cause currently
Nicolas Zea 2011/01/20 20:01:57 unnecessary "it"?
tim (not reviewing) 2011/01/25 03:23:05 Done.
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)
akalin 2011/01/20 00:47:57 move the body into the .cc file
tim (not reviewing) 2011/01/25 03:23:05 Done.
104 : mode(mode), length(length), had_nudge(false) { }
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 const base::TimeTicks scheduled_start;
125 linked_ptr<sessions::SyncSession> session;
126 };
127
128 // Helper to assemble a job and post a delayed task to sync.
129 void ScheduleSyncSessionJob(const base::TimeDelta& delay,
130 SyncSessionJob::Purpose purpose,
131 sessions::SyncSession* session);
132
133 // Invoke the Syncer to perform a sync.
134 void DoSyncSessionJob(const SyncSessionJob& job);
Nicolas Zea 2011/01/20 20:01:57 Might be more consistent if named SyncSessionJobIm
tim (not reviewing) 2011/01/25 03:23:05 Hmm.. well the others have the same prefix. Here
135
136 // Called after the Syncer has performed the sync represented by |job|, to
137 // reset our state.
138 void FinishSyncSessionJob(const SyncSessionJob& job);
139
140 // Helper to FinishSyncSessionJob to schedule the next sync operation.
141 void ScheduleNextSync(const SyncSessionJob& old_job);
142
143 // Helper to configure polling intervals. Used by Start and ScheduleNextSync.
144 void AdjustPolling(const SyncSessionJob* old_job);
145
146 // Helper to ScheduleNextSync in case of consecutive sync errors.
147 void HandleConsecutiveContinuationError(const SyncSessionJob& old_job);
148
149 // Determines if it is legal to run a sync job for |purpose| at
150 // |scheduled_start|. This checks current operational mode, backoff or
151 // throttling, freshness (so we don't make redundant syncs), and connection.
152 bool ShouldRunJob(SyncSessionJob::Purpose purpose,
153 const base::TimeTicks& scheduled_start);
154
155 // 'Impl' here refers to real implementation of public functions, running on
156 // |thread_|.
157 void StartImpl(Mode mode);
158 void ScheduleNudgeImpl(const base::TimeDelta& delay,
159 NudgeSource source,
160 const syncable::ModelTypeBitSet& model_types);
161 void ScheduleConfigImpl(const base::TimeDelta& delay,
162 const ModelSafeRoutingInfo& routing_info,
163 const std::vector<ModelSafeWorker*>& workers);
164
165 // Returns true if the client is currently in exponential backoff.
166 bool IsBackingOff() const;
167
168 // Helper to signal all listeners registered with |session_context_|.
169 void Notify(SyncEngineEvent::EventCause cause);
170
171 // ServerConnectionEventListener implementation.
172 // TODO(tim): schedule a nudge when valid connection detected? in 1 minute?
173 virtual void OnServerConnectionEvent(const ServerConnectionEvent& event);
174
175 // Callback to change backoff state.
176 void DoCanaryJob();
177 void Unthrottle();
178
179 // Creates a session for a poll and performs the sync.
180 void PollTimerCallback();
181
182 base::Thread thread_;
183
184 // Modifiable versions of kDefaultLongPollIntervalSeconds which can be
185 // updated by the server.
186 base::TimeDelta syncer_short_poll_interval_seconds_;
187 base::TimeDelta syncer_long_poll_interval_seconds_;
188
189 // Periodic timer for polling. See AdjustPolling.
190 base::RepeatingTimer<SyncerThread> poll_timer_;
191
192 // The mode of operation. We don't use a lock, see Start(...) comment.
193 Mode mode_;
194
195 // TODO(tim): Bug 26339. This needs to track more than just time I think,
196 // since the nudges could be for different types. Current impl doesn't care.
197 base::TimeTicks last_sync_session_end_time_;
198
199 // Have we observed a valid server connection?
200 bool server_connection_ok_;
201
202 // Tracks in-flight nudges so we can coalesce.
203 scoped_ptr<SyncSessionJob> pending_nudge_;
204
205 // Current wait state. Null if we're not in backoff and not throttled.
206 scoped_ptr<WaitInterval> wait_interval_;
207
208 // Invoked to run through the sync cycle.
209 scoped_ptr<Syncer> syncer_;
210
211 scoped_ptr<sessions::SyncSessionContext> session_context_;
212
213 DISALLOW_COPY_AND_ASSIGN(SyncerThread);
214 };
215
216 // The SyncerThread manages its own internal thread and thus outlives it. We
217 // don't need refcounting for posting tasks to this internal thread.
218 DISABLE_RUNNABLE_METHOD_REFCOUNT(SyncerThread);
219
220 } // namespace s3
221
222 } // namespace browser_sync
223
224 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD2_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698