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

Side by Side Diff: sync/engine/sync_scheduler_impl.h

Issue 10917234: sync: make scheduling logic and job ownership more obvious. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: test + comment + rebase Created 8 years, 3 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #ifndef SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_ 5 #ifndef SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_
6 #define SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_ 6 #define SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_
7 7
8 #include <map> 8 #include <map>
9 #include <string> 9 #include <string>
10 10
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/gtest_prod_util.h" 13 #include "base/gtest_prod_util.h"
14 #include "base/memory/linked_ptr.h" 14 #include "base/memory/linked_ptr.h"
15 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/weak_ptr.h" 16 #include "base/memory/weak_ptr.h"
17 #include "base/observer_list.h" 17 #include "base/observer_list.h"
18 #include "base/time.h" 18 #include "base/time.h"
19 #include "base/timer.h" 19 #include "base/timer.h"
20 #include "sync/engine/net/server_connection_manager.h" 20 #include "sync/engine/net/server_connection_manager.h"
21 #include "sync/engine/nudge_source.h" 21 #include "sync/engine/nudge_source.h"
22 #include "sync/engine/sync_scheduler.h" 22 #include "sync/engine/sync_scheduler.h"
23 #include "sync/engine/sync_session_job.h"
23 #include "sync/engine/syncer.h" 24 #include "sync/engine/syncer.h"
24 #include "sync/internal_api/public/base/model_type_state_map.h" 25 #include "sync/internal_api/public/base/model_type_state_map.h"
25 #include "sync/internal_api/public/engine/polling_constants.h" 26 #include "sync/internal_api/public/engine/polling_constants.h"
26 #include "sync/internal_api/public/util/weak_handle.h" 27 #include "sync/internal_api/public/util/weak_handle.h"
27 #include "sync/sessions/sync_session.h" 28 #include "sync/sessions/sync_session.h"
28 #include "sync/sessions/sync_session_context.h" 29 #include "sync/sessions/sync_session_context.h"
29 30
30 namespace syncer { 31 namespace syncer {
31 32
32 class BackoffDelayProvider; 33 class BackoffDelayProvider;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 private: 81 private:
81 enum JobProcessDecision { 82 enum JobProcessDecision {
82 // Indicates we should continue with the current job. 83 // Indicates we should continue with the current job.
83 CONTINUE, 84 CONTINUE,
84 // Indicates that we should save it to be processed later. 85 // Indicates that we should save it to be processed later.
85 SAVE, 86 SAVE,
86 // Indicates we should drop this job. 87 // Indicates we should drop this job.
87 DROP, 88 DROP,
88 }; 89 };
89 90
90 struct SyncSessionJob {
91 // An enum used to describe jobs for scheduling purposes.
92 enum SyncSessionJobPurpose {
93 // Uninitialized state, should never be hit in practice.
94 UNKNOWN = -1,
95 // Our poll timer schedules POLL jobs periodically based on a server
96 // assigned poll interval.
97 POLL,
98 // A nudge task can come from a variety of components needing to force
99 // a sync. The source is inferable from |session.source()|.
100 NUDGE,
101 // Typically used for fetching updates for a subset of the enabled types
102 // during initial sync or reconfiguration.
103 CONFIGURATION,
104 };
105 SyncSessionJob();
106 SyncSessionJob(SyncSessionJobPurpose purpose, base::TimeTicks start,
107 linked_ptr<sessions::SyncSession> session, bool is_canary_job,
108 const ConfigurationParams& config_params,
109 const tracked_objects::Location& nudge_location);
110 ~SyncSessionJob();
111 static const char* GetPurposeString(SyncSessionJobPurpose purpose);
112
113 SyncSessionJobPurpose purpose;
114 base::TimeTicks scheduled_start;
115 linked_ptr<sessions::SyncSession> session;
116 bool is_canary_job;
117 ConfigurationParams config_params;
118
119 // This is the location the job came from. Used for debugging.
120 // In case of multiple nudges getting coalesced this stores the
121 // first location that came in.
122 tracked_objects::Location from_here;
123 };
124 friend class SyncSchedulerTest; 91 friend class SyncSchedulerTest;
125 friend class SyncSchedulerWhiteboxTest; 92 friend class SyncSchedulerWhiteboxTest;
126 friend class SyncerTest; 93 friend class SyncerTest;
127 94
128 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerWhiteboxTest, 95 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerWhiteboxTest,
129 DropNudgeWhileExponentialBackOff); 96 DropNudgeWhileExponentialBackOff);
130 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerWhiteboxTest, SaveNudge); 97 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerWhiteboxTest, SaveNudge);
131 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerWhiteboxTest, 98 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerWhiteboxTest,
132 SaveNudgeWhileTypeThrottled); 99 SaveNudgeWhileTypeThrottled);
133 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerWhiteboxTest, ContinueNudge); 100 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerWhiteboxTest, ContinueNudge);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 132
166 Mode mode; 133 Mode mode;
167 134
168 // This bool is set to true if we have observed a nudge during this 135 // This bool is set to true if we have observed a nudge during this
169 // interval and mode == EXPONENTIAL_BACKOFF. 136 // interval and mode == EXPONENTIAL_BACKOFF.
170 bool had_nudge; 137 bool had_nudge;
171 base::TimeDelta length; 138 base::TimeDelta length;
172 base::OneShotTimer<SyncSchedulerImpl> timer; 139 base::OneShotTimer<SyncSchedulerImpl> timer;
173 140
174 // Configure jobs are saved only when backing off or throttling. So we 141 // Configure jobs are saved only when backing off or throttling. So we
175 // expose the pointer here. 142 // expose the pointer here (does not own, similar to pending_nudge).
176 scoped_ptr<SyncSessionJob> pending_configure_job; 143 SyncSessionJob* pending_configure_job;
177 }; 144 };
178 145
179 static const char* GetModeString(Mode mode); 146 static const char* GetModeString(Mode mode);
180 147
181 static const char* GetDecisionString(JobProcessDecision decision); 148 static const char* GetDecisionString(JobProcessDecision decision);
182 149
183 // Assign |start| and |end| to appropriate SyncerStep values for the
184 // specified |purpose|.
185 static void SetSyncerStepsForPurpose(
186 SyncSessionJob::SyncSessionJobPurpose purpose,
187 SyncerStep* start, SyncerStep* end);
188
189 // Helpers that log before posting to |sync_loop_|. These will only post 150 // Helpers that log before posting to |sync_loop_|. These will only post
190 // the task in between calls to Start/Stop. 151 // the task in between calls to Start/Stop.
191 void PostTask(const tracked_objects::Location& from_here, 152 void PostTask(const tracked_objects::Location& from_here,
192 const char* name, 153 const char* name,
193 const base::Closure& task); 154 const base::Closure& task);
194 void PostDelayedTask(const tracked_objects::Location& from_here, 155 void PostDelayedTask(const tracked_objects::Location& from_here,
195 const char* name, 156 const char* name,
196 const base::Closure& task, 157 const base::Closure& task,
197 base::TimeDelta delay); 158 base::TimeDelta delay);
198 159
199 // Helper to assemble a job and post a delayed task to sync. 160 // Helper to assemble a job and post a delayed task to sync.
200 void ScheduleSyncSessionJob(const SyncSessionJob& job); 161 void ScheduleSyncSessionJob(scoped_ptr<SyncSessionJob> job);
201 162
202 // Invoke the Syncer to perform a sync. 163 // Invoke the Syncer to perform a sync.
203 void DoSyncSessionJob(const SyncSessionJob& job); 164 bool DoSyncSessionJob(scoped_ptr<SyncSessionJob> job);
204 165
205 // Called after the Syncer has performed the sync represented by |job|, to 166 // Called after the Syncer has performed the sync represented by |job|, to
206 // reset our state. 167 // reset our state. |premature_exit| is true if the Syncer did not manage
207 void FinishSyncSessionJob(const SyncSessionJob& job); 168 // to cycle from job.start_step() to job.end_step(), likely because the
169 // scheduler was forced to quit the job mid-way through.
170 void FinishSyncSessionJob(SyncSessionJob* job, bool exited_prematurely);
208 171
209 // Helper to FinishSyncSessionJob to schedule the next sync operation. 172 // Helper to FinishSyncSessionJob to schedule the next sync operation.
210 void ScheduleNextSync(const SyncSessionJob& old_job); 173 void ScheduleNextSync(const SyncSessionJob* old_job);
211 174
212 // Helper to configure polling intervals. Used by Start and ScheduleNextSync. 175 // Helper to configure polling intervals. Used by Start and ScheduleNextSync.
213 void AdjustPolling(const SyncSessionJob* old_job); 176 void AdjustPolling(const SyncSessionJob* old_job);
214 177
215 // Helper to restart waiting with |wait_interval_|'s timer. 178 // Helper to restart waiting with |wait_interval_|'s timer.
216 void RestartWaiting(); 179 void RestartWaiting(scoped_ptr<SyncSessionJob> job);
217 180
218 // Helper to ScheduleNextSync in case of consecutive sync errors. 181 // Helper to ScheduleNextSync in case of consecutive sync errors.
219 void HandleContinuationError(const SyncSessionJob& old_job); 182 void HandleContinuationError(const SyncSessionJob* old_job);
220 183
221 // Determines if it is legal to run |job| by checking current 184 // Determines if it is legal to run |job| by checking current
222 // operational mode, backoff or throttling, freshness 185 // operational mode, backoff or throttling and connection. If the job is
223 // (so we don't make redundant syncs), and connection. 186 // not fit to run at this time, this function returns false, and the caller
224 bool ShouldRunJob(const SyncSessionJob& job); 187 // should not proceed to run job. If that happens (the function returns
188 // false), the caller can rest assured that the job was rescheduled for
189 // later if it was deemed important, so the caller is not responsible.
190 bool ShouldRunJobSaveIfNecessary(SyncSessionJob* job);
225 191
226 // Decide whether we should CONTINUE, SAVE or DROP the job. 192 // Decide whether we should CONTINUE, SAVE or DROP the job.
227 JobProcessDecision DecideOnJob(const SyncSessionJob& job); 193 JobProcessDecision DecideOnJob(const SyncSessionJob* job);
228 194
229 // Decide on whether to CONTINUE, SAVE or DROP the job when we are in 195 // Decide on whether to CONTINUE, SAVE or DROP the job when we are in
230 // backoff mode. 196 // backoff mode.
231 JobProcessDecision DecideWhileInWaitInterval(const SyncSessionJob& job); 197 JobProcessDecision DecideWhileInWaitInterval(const SyncSessionJob* job);
232
233 // Saves the job for future execution. Note: It drops all the poll jobs.
234 void SaveJob(const SyncSessionJob& job);
235
236 // Coalesces the current job with the pending nudge.
237 void InitOrCoalescePendingJob(const SyncSessionJob& job);
238 198
239 // 'Impl' here refers to real implementation of public functions, running on 199 // 'Impl' here refers to real implementation of public functions, running on
240 // |thread_|. 200 // |thread_|.
241 void StopImpl(const base::Closure& callback); 201 void StopImpl(const base::Closure& callback);
242 void ScheduleNudgeImpl( 202 void ScheduleNudgeImpl(
243 const base::TimeDelta& delay, 203 const base::TimeDelta& delay,
244 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, 204 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source,
245 const ModelTypeStateMap& type_state_map, 205 const ModelTypeStateMap& type_state_map,
246 bool is_canary_job, const tracked_objects::Location& nudge_location); 206 const tracked_objects::Location& nudge_location);
247 207
248 // Returns true if the client is currently in exponential backoff. 208 // Returns true if the client is currently in exponential backoff.
249 bool IsBackingOff() const; 209 bool IsBackingOff() const;
250 210
251 // Helper to signal all listeners registered with |session_context_|. 211 // Helper to signal all listeners registered with |session_context_|.
252 void Notify(SyncEngineEvent::EventCause cause); 212 void Notify(SyncEngineEvent::EventCause cause);
253 213
254 // Callback to change backoff state. 214 // Callback to change backoff state. |to_be_canary| in both cases is the job
255 void DoCanaryJob(); 215 // that should be granted canary privileges. Note: it is possible that the
256 void Unthrottle(); 216 // job that gets scheduled when this callback is scheduled is different from
217 // the job that will actually get executed, because other jobs may have been
218 // scheduled while we were waiting for the callback.
219 void DoCanaryJob(scoped_ptr<SyncSessionJob> to_be_canary);
220 void Unthrottle(scoped_ptr<SyncSessionJob> to_be_canary);
257 221
258 // Executes the pending job. Called whenever an event occurs that may 222 // Returns a pending job that has potential to run given the state of the
259 // change conditions permitting a job to run. Like when network connection is 223 // scheduler, if it exists. Useful whenever an event occurs that may
260 // re-established, mode changes etc. 224 // change conditions that permit a job to run, such as re-establishing
261 void DoPendingJobIfPossible(bool is_canary_job); 225 // network connection, auth refresh, mode changes etc. Note that the returned
226 // job may have been scheduled to run at a later time, or may have been
227 // unscheduled. In the former case, this will result in abandoning the old
228 // job and effectively cancelling it.
229 scoped_ptr<SyncSessionJob> TakePendingJobForCurrentMode();
262 230
263 // Called when the root cause of the current connection error is fixed. 231 // Called when the root cause of the current connection error is fixed.
264 void OnServerConnectionErrorFixed(); 232 void OnServerConnectionErrorFixed();
265 233
266 // The pointer is owned by the caller. 234 // The pointer is owned by the caller.
rlarocque 2012/09/24 21:15:14 I think this comment is no longer necessary.
tim (not reviewing) 2012/10/08 00:20:03 Done.
267 sessions::SyncSession* CreateSyncSession( 235 scoped_ptr<sessions::SyncSession> CreateSyncSession(
268 const sessions::SyncSourceInfo& info); 236 const sessions::SyncSourceInfo& info);
269 237
270 // Creates a session for a poll and performs the sync. 238 // Creates a session for a poll and performs the sync.
271 void PollTimerCallback(); 239 void PollTimerCallback();
272 240
273 // Used to update |connection_code_|, see below. 241 // Used to update |connection_code_|, see below.
274 void UpdateServerConnectionManagerStatus( 242 void UpdateServerConnectionManagerStatus(
275 HttpResponse::ServerConnectionCode code); 243 HttpResponse::ServerConnectionCode code);
276 244
277 // Called once the first time thread_ is started to broadcast an initial 245 // Called once the first time thread_ is started to broadcast an initial
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 284
317 // Periodic timer for polling. See AdjustPolling. 285 // Periodic timer for polling. See AdjustPolling.
318 base::RepeatingTimer<SyncSchedulerImpl> poll_timer_; 286 base::RepeatingTimer<SyncSchedulerImpl> poll_timer_;
319 287
320 // The mode of operation. 288 // The mode of operation.
321 Mode mode_; 289 Mode mode_;
322 290
323 // The latest connection code we got while trying to connect. 291 // The latest connection code we got while trying to connect.
324 HttpResponse::ServerConnectionCode connection_code_; 292 HttpResponse::ServerConnectionCode connection_code_;
325 293
326 // Tracks in-flight nudges so we can coalesce. 294 // Tracks (does not own) in-flight nudges (scheduled or unscheduled),
327 scoped_ptr<SyncSessionJob> pending_nudge_; 295 // so we can coalesce. NULL if there is no pending nudge.
296 SyncSessionJob* pending_nudge_;
297
298 // There are certain situations where we want to remember a nudge, but
299 // there is no well defined moment in time in the future when that nudge
300 // should run, e.g. if it requires a mode switch or updated auth credentials.
301 // This member will own NUDGE jobs in those cases, until an external event
302 // (mode switch or fixed auth) occurs to trigger a retry. Should be treated
303 // as opaque / not interacted with (i.e. we could build a wrapper to
304 // hide the type, but that's probably overkill).
305 scoped_ptr<SyncSessionJob> unscheduled_nudge_storage_;
rlarocque 2012/09/24 22:01:46 I didn't see anywhere in this patch where we read
tim (not reviewing) 2012/10/08 00:20:03 Right, as I said in the comment, we should not rea
328 306
329 // Current wait state. Null if we're not in backoff and not throttled. 307 // Current wait state. Null if we're not in backoff and not throttled.
330 scoped_ptr<WaitInterval> wait_interval_; 308 scoped_ptr<WaitInterval> wait_interval_;
331 309
332 scoped_ptr<BackoffDelayProvider> delay_provider_; 310 scoped_ptr<BackoffDelayProvider> delay_provider_;
333 311
334 // Invoked to run through the sync cycle. 312 // Invoked to run through the sync cycle.
335 scoped_ptr<Syncer> syncer_; 313 scoped_ptr<Syncer> syncer_;
336 314
337 sessions::SyncSessionContext* session_context_; 315 sessions::SyncSessionContext* session_context_;
(...skipping 10 matching lines...) Expand all
348 // take place during a sync cycle. We call this out because such violations 326 // take place during a sync cycle. We call this out because such violations
349 // could result in tight sync loops hitting sync servers. 327 // could result in tight sync loops hitting sync servers.
350 bool no_scheduling_allowed_; 328 bool no_scheduling_allowed_;
351 329
352 DISALLOW_COPY_AND_ASSIGN(SyncSchedulerImpl); 330 DISALLOW_COPY_AND_ASSIGN(SyncSchedulerImpl);
353 }; 331 };
354 332
355 } // namespace syncer 333 } // namespace syncer
356 334
357 #endif // SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_ 335 #endif // SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698