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

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

Issue 6812004: sync: Make nudge + config jobs reliable in SyncerThread2 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixing CR feedback. 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 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD2_H_ 6 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD2_H_
7 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD2_H_ 7 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD2_H_
8 #pragma once 8 #pragma once
9 9
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 const base::TimeDelta& new_interval); 92 const base::TimeDelta& new_interval);
93 virtual void OnReceivedLongPollIntervalUpdate( 93 virtual void OnReceivedLongPollIntervalUpdate(
94 const base::TimeDelta& new_interval); 94 const base::TimeDelta& new_interval);
95 virtual void OnShouldStopSyncingPermanently(); 95 virtual void OnShouldStopSyncingPermanently();
96 96
97 // ServerConnectionEventListener implementation. 97 // ServerConnectionEventListener implementation.
98 // TODO(tim): schedule a nudge when valid connection detected? in 1 minute? 98 // TODO(tim): schedule a nudge when valid connection detected? in 1 minute?
99 virtual void OnServerConnectionEvent(const ServerConnectionEvent2& event); 99 virtual void OnServerConnectionEvent(const ServerConnectionEvent2& event);
100 100
101 private: 101 private:
102 friend class SyncerThread2Test; 102 enum JobProcessDecision {
103 103 // Indicates we should continue with the current job.
104 // State pertaining to exponential backoff or throttling periods. 104 CONTINUE,
105 struct WaitInterval; 105 // Indicates that we should save it to be processed later.
106 106 SAVE,
107 // An enum used to describe jobs for scheduling purposes. 107 // Indicates we should drop this job.
108 enum SyncSessionJobPurpose { 108 DROP,
109 // Our poll timer schedules POLL jobs periodically based on a server
110 // assigned poll interval.
111 POLL,
112 // A nudge task can come from a variety of components needing to force
113 // a sync. The source is inferable from |session.source()|.
114 NUDGE,
115 // The user invoked a function in the UI to clear their entire account
116 // and stop syncing (globally).
117 CLEAR_USER_DATA,
118 // Typically used for fetching updates for a subset of the enabled types
119 // during initial sync or reconfiguration. We don't run all steps of
120 // the sync cycle for these (e.g. CleanupDisabledTypes is skipped).
121 CONFIGURATION,
122 }; 109 };
123 110
124 // Internal state for every sync task that is scheduled. 111 struct SyncSessionJob {
125 struct SyncSessionJob; 112 // An enum used to describe jobs for scheduling purposes.
113 enum SyncSessionJobPurpose {
114 // Our poll timer schedules POLL jobs periodically based on a server
115 // assigned poll interval.
116 POLL,
117 // A nudge task can come from a variety of components needing to force
118 // a sync. The source is inferable from |session.source()|.
119 NUDGE,
120 // The user invoked a function in the UI to clear their entire account
121 // and stop syncing (globally).
122 CLEAR_USER_DATA,
123 // Typically used for fetching updates for a subset of the enabled types
124 // during initial sync or reconfiguration. We don't run all steps of
125 // the sync cycle for these (e.g. CleanupDisabledTypes is skipped).
126 CONFIGURATION,
127 };
128 SyncSessionJob();
129 SyncSessionJob(SyncSessionJobPurpose purpose, base::TimeTicks start,
130 linked_ptr<sessions::SyncSession> session, bool is_canary_job,
131 const tracked_objects::Location& nudge_location);
132 ~SyncSessionJob();
133 SyncSessionJobPurpose purpose;
134 base::TimeTicks scheduled_start;
135 linked_ptr<sessions::SyncSession> session;
136 bool is_canary_job;
137
138 // This is the location the nudge came from. used for debugging purpose.
139 // In case of multiple nudges getting coalesced this stores the first nudge
140 // that came in.
141 tracked_objects::Location nudge_location;
142 };
143 friend class SyncerThread2Test;
144 friend class SyncerThread2WhiteboxTest;
145 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
146 DropNudgeWhileExponentialBackOff);
147
tim (not reviewing) 2011/04/13 23:31:54 extra newline but also, are you sure it's not pos
lipalani1 2011/04/14 00:51:07 I am assuming you mean to use TEST() rather than T
tim (not reviewing) 2011/04/14 23:09:44 I meant adding methods to the class like SetFoo()
148 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, SaveNudge);
149 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, ContinueNudge);
150 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, DropPoll);
151 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, ContinuePoll);
152 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, ContinueConfiguration);
153 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
154 SaveConfigurationWhileThrottled);
155 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
156 SaveNudgeWhileThrottled);
157 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
158 ContinueClearUserDataUnderAllCircumstances);
159 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
160 DropNudgeWhileExponentialBackOff);
161 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
162 ContinueCanaryJobConfig);
163 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
164 ContinueNudgeWhileExponentialBackOff);
126 165
127 // A component used to get time delays associated with exponential backoff. 166 // A component used to get time delays associated with exponential backoff.
128 // Encapsulated into a class to facilitate testing. 167 // Encapsulated into a class to facilitate testing.
129 class DelayProvider { 168 class DelayProvider {
130 public: 169 public:
131 DelayProvider(); 170 DelayProvider();
132 virtual base::TimeDelta GetDelay(const base::TimeDelta& last_delay); 171 virtual base::TimeDelta GetDelay(const base::TimeDelta& last_delay);
133 virtual ~DelayProvider(); 172 virtual ~DelayProvider();
134 private: 173 private:
135 DISALLOW_COPY_AND_ASSIGN(DelayProvider); 174 DISALLOW_COPY_AND_ASSIGN(DelayProvider);
136 }; 175 };
137 176
177 struct WaitInterval {
178 enum Mode {
179 // A wait interval whose duration has been affected by exponential
180 // backoff.
181 // EXPONENTIAL_BACKOFF intervals are nudge-rate limited to 1 per interval.
182 EXPONENTIAL_BACKOFF,
183 // A server-initiated throttled interval. We do not allow any syncing
184 // during such an interval.
185 THROTTLED,
186 };
187 WaitInterval();
188 ~WaitInterval();
189
190 Mode mode;
191
192 // This bool is set to true if we have observed a nudge during this
193 // interval and mode == EXPONENTIAL_BACKOFF.
194 bool had_nudge;
195 base::TimeDelta length;
196 base::OneShotTimer<SyncerThread> timer;
197
198 // Configure jobs are saved only when backing off or throttling. So we
199 // expose the pointer here.
200 scoped_ptr<SyncSessionJob> pending_configure_job;
201 WaitInterval(Mode mode, base::TimeDelta length);
202 };
203
138 // Helper to assemble a job and post a delayed task to sync. 204 // Helper to assemble a job and post a delayed task to sync.
139 void ScheduleSyncSessionJob(const base::TimeDelta& delay, 205 void ScheduleSyncSessionJob(const base::TimeDelta& delay,
140 SyncSessionJobPurpose purpose, 206 SyncSessionJob::SyncSessionJobPurpose purpose,
tim (not reviewing) 2011/04/13 23:31:54 two more spaces indent, which means the |delay| pa
lipalani1 2011/04/14 00:51:07 Done.
141 sessions::SyncSession* session, 207 sessions::SyncSession* session,
142 const tracked_objects::Location& nudge_location); 208 const tracked_objects::Location& nudge_location);
143 209
144 // Invoke the Syncer to perform a sync. 210 // Invoke the Syncer to perform a sync.
145 void DoSyncSessionJob(const SyncSessionJob& job); 211 void DoSyncSessionJob(const SyncSessionJob& job);
146 212
147 // Called after the Syncer has performed the sync represented by |job|, to 213 // Called after the Syncer has performed the sync represented by |job|, to
148 // reset our state. 214 // reset our state.
149 void FinishSyncSessionJob(const SyncSessionJob& job); 215 void FinishSyncSessionJob(const SyncSessionJob& job);
150 216
151 // Record important state that might be needed in future syncs, such as which 217 // Record important state that might be needed in future syncs, such as which
152 // data types may require cleanup. 218 // data types may require cleanup.
153 void UpdateCarryoverSessionState(const SyncSessionJob& old_job); 219 void UpdateCarryoverSessionState(const SyncSessionJob& old_job);
154 220
155 // Helper to FinishSyncSessionJob to schedule the next sync operation. 221 // Helper to FinishSyncSessionJob to schedule the next sync operation.
156 void ScheduleNextSync(const SyncSessionJob& old_job); 222 void ScheduleNextSync(const SyncSessionJob& old_job);
157 223
158 // Helper to configure polling intervals. Used by Start and ScheduleNextSync. 224 // Helper to configure polling intervals. Used by Start and ScheduleNextSync.
159 void AdjustPolling(const SyncSessionJob* old_job); 225 void AdjustPolling(const SyncSessionJob* old_job);
160 226
161 // Helper to ScheduleNextSync in case of consecutive sync errors. 227 // Helper to ScheduleNextSync in case of consecutive sync errors.
162 void HandleConsecutiveContinuationError(const SyncSessionJob& old_job); 228 void HandleConsecutiveContinuationError(const SyncSessionJob& old_job);
163 229
164 // Determines if it is legal to run a sync job for |purpose| at 230 // Determines if it is legal to run |job|.
tim (not reviewing) 2011/04/13 23:31:54 "to run |job| by checking current operational mode
lipalani1 2011/04/14 00:51:07 Done.
165 // |scheduled_start|. This checks current operational mode, backoff or 231 // This checks current operational mode, backoff or
166 // throttling, freshness (so we don't make redundant syncs), and connection. 232 // throttling, freshness (so we don't make redundant syncs), and connection.
167 bool ShouldRunJob(SyncSessionJobPurpose purpose, 233 bool ShouldRunJob(const SyncSessionJob& job);
168 const base::TimeTicks& scheduled_start); 234
235 // Decide whether we should continue, save or discard the job.
tim (not reviewing) 2011/04/13 23:31:54 swap discard for drop
lipalani1 2011/04/14 00:51:07 Done.
236 JobProcessDecision DecideOnJob(const SyncSessionJob& job);
237
238 // Decide on whether to run, save or discard the job when we are in
tim (not reviewing) 2011/04/13 23:31:54 CONTINUE, SAVE, DROP
lipalani1 2011/04/14 00:51:07 Done.
239 // backoff mode.
240 JobProcessDecision DecideWhileInWaitInterval(const SyncSessionJob& job);
241
242 // Saves the job for future execution. Note: It drops all the poll jobs.
243 void SaveJob(const SyncSessionJob& job);
244
245 // Coalesces the current job with the pending nudge.
246 void InitOrCoalescePendingJob(const SyncSessionJob& job);
169 247
170 // 'Impl' here refers to real implementation of public functions, running on 248 // 'Impl' here refers to real implementation of public functions, running on
171 // |thread_|. 249 // |thread_|.
172 void StartImpl(Mode mode, linked_ptr<ModeChangeCallback> callback); 250 void StartImpl(Mode mode, linked_ptr<ModeChangeCallback> callback);
173 void ScheduleNudgeImpl( 251 void ScheduleNudgeImpl(
174 const base::TimeDelta& delay, 252 const base::TimeDelta& delay,
175 NudgeSource source, 253 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source,
176 const syncable::ModelTypePayloadMap& types_with_payloads, 254 const syncable::ModelTypePayloadMap& types_with_payloads,
177 const tracked_objects::Location& nudge_location); 255 bool is_canary_job, const tracked_objects::Location& nudge_location);
178 void ScheduleConfigImpl(const ModelSafeRoutingInfo& routing_info, 256 void ScheduleConfigImpl(const ModelSafeRoutingInfo& routing_info,
179 const std::vector<ModelSafeWorker*>& workers); 257 const std::vector<ModelSafeWorker*>& workers,
258 const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source);
180 void ScheduleClearUserDataImpl(); 259 void ScheduleClearUserDataImpl();
181 260
182 // Returns true if the client is currently in exponential backoff. 261 // Returns true if the client is currently in exponential backoff.
183 bool IsBackingOff() const; 262 bool IsBackingOff() const;
184 263
185 // Helper to signal all listeners registered with |session_context_|. 264 // Helper to signal all listeners registered with |session_context_|.
186 void Notify(SyncEngineEvent::EventCause cause); 265 void Notify(SyncEngineEvent::EventCause cause);
187 266
188 // Callback to change backoff state. 267 // Callback to change backoff state.
189 void DoCanaryJob(); 268 void DoCanaryJob();
190 void Unthrottle(); 269 void Unthrottle();
191 270
271 // Executes jobs that are pending. Called whenever a critical event
tim (not reviewing) 2011/04/13 23:31:54 There's only one pending job, so shouldn't be plur
lipalani1 2011/04/14 00:51:07 Done.
272 // happens. Like when network connection is established, mode changes etc.
273 void DoPendingJobIfPossible(bool is_canary_job);
274
275 // The pointer is owned by the caller.
276 browser_sync::sessions::SyncSession* CreateSyncSession(
277 const browser_sync::sessions::SyncSourceInfo& info);
278
192 // Creates a session for a poll and performs the sync. 279 // Creates a session for a poll and performs the sync.
193 void PollTimerCallback(); 280 void PollTimerCallback();
194 281
195 // Assign |start| and |end| to appropriate SyncerStep values for the 282 // Assign |start| and |end| to appropriate SyncerStep values for the
196 // specified |purpose|. 283 // specified |purpose|.
197 void SetSyncerStepsForPurpose(SyncSessionJobPurpose purpose, 284 void SetSyncerStepsForPurpose(SyncSessionJob::SyncSessionJobPurpose purpose,
198 SyncerStep* start, 285 SyncerStep* start,
199 SyncerStep* end); 286 SyncerStep* end);
200 287
201 // Initializes the hookup between the ServerConnectionManager and us. 288 // Initializes the hookup between the ServerConnectionManager and us.
202 void WatchConnectionManager(); 289 void WatchConnectionManager();
203 290
204 // Used to update |server_connection_ok_|, see below. 291 // Used to update |server_connection_ok_|, see below.
205 void CheckServerConnectionManagerStatus( 292 void CheckServerConnectionManagerStatus(
206 HttpResponse::ServerConnectionCode code); 293 HttpResponse::ServerConnectionCode code);
207 294
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 335
249 } // namespace s3 336 } // namespace s3
250 337
251 } // namespace browser_sync 338 } // namespace browser_sync
252 339
253 // The SyncerThread manages its own internal thread and thus outlives it. We 340 // The SyncerThread manages its own internal thread and thus outlives it. We
254 // don't need refcounting for posting tasks to this internal thread. 341 // don't need refcounting for posting tasks to this internal thread.
255 DISABLE_RUNNABLE_METHOD_REFCOUNT(browser_sync::s3::SyncerThread); 342 DISABLE_RUNNABLE_METHOD_REFCOUNT(browser_sync::s3::SyncerThread);
256 343
257 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD2_H_ 344 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD2_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698