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

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

Issue 13422003: sync: Refactor job ownership in SyncScheduler (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Attempt to fix subtle problem with nudge-in-backoff handling Created 7 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
« no previous file with comments | « no previous file | sync/engine/sync_scheduler_impl.cc » ('j') | sync/engine/sync_scheduler_impl.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 143
144 static const char* GetModeString(Mode mode); 144 static const char* GetModeString(Mode mode);
145 145
146 Mode mode; 146 Mode mode;
147 147
148 // This bool is set to true if we have observed a nudge during this 148 // This bool is set to true if we have observed a nudge during this
149 // interval and mode == EXPONENTIAL_BACKOFF. 149 // interval and mode == EXPONENTIAL_BACKOFF.
150 bool had_nudge; 150 bool had_nudge;
151 base::TimeDelta length; 151 base::TimeDelta length;
152 base::OneShotTimer<SyncSchedulerImpl> timer; 152 base::OneShotTimer<SyncSchedulerImpl> timer;
153
154 // Configure jobs are saved only when backing off or throttling. So we
155 // expose the pointer here (does not own, similar to pending_nudge).
156 SyncSessionJob* pending_configure_job;
157 }; 153 };
158 154
159 static const char* GetModeString(Mode mode); 155 static const char* GetModeString(Mode mode);
160 156
161 static const char* GetDecisionString(JobProcessDecision decision); 157 static const char* GetDecisionString(JobProcessDecision decision);
162 158
163 // Helper to cancel any existing delayed task and replace it with a new one. 159 // Helper to cancel any existing delayed task and replace it with a new one.
164 // It will not post any tasks if the scheduler is in a "stopped" state. 160 // It will not post any tasks if the scheduler is in a "stopped" state.
165 void PostDelayedTask(const tracked_objects::Location& from_here, 161 void PostDelayedTask(const tracked_objects::Location& from_here,
166 const char* name, 162 const char* name,
167 const base::Closure& task, 163 const base::Closure& task,
168 base::TimeDelta delay); 164 base::TimeDelta delay);
169 165
170 // Invoke the Syncer to perform a non-poll job. 166 // Invoke the syncer to perform a non-POLL job.
171 bool DoSyncSessionJob(scoped_ptr<SyncSessionJob> job, 167 bool DoSyncSessionJobImpl(scoped_ptr<SyncSessionJob> job,
172 JobPriority priority); 168 JobPriority priority);
169
170 // Invoke the syncer to perform a nudge job.
171 bool DoNudgeSyncSessionJob(JobPriority priority);
172
173 // Invoke the syncer to perform a configuration job.
174 bool DoConfigurationSyncSessionJob(JobPriority priority);
173 175
174 // Returns whether or not it's safe to run a poll job at this time. 176 // Returns whether or not it's safe to run a poll job at this time.
175 bool ShouldPoll(); 177 bool ShouldPoll();
176 178
177 // Invoke the Syncer to perform a poll job. 179 // Invoke the Syncer to perform a poll job.
178 void DoPollSyncSessionJob(scoped_ptr<SyncSessionJob> job); 180 void DoPollSyncSessionJob();
179 181
180 // Called after the Syncer has performed the sync represented by |job|, to 182 // Called after the Syncer has performed the sync represented by |job|, to
181 // reset our state. |exited_prematurely| is true if the Syncer did not 183 // reset our state. |exited_prematurely| is true if the Syncer did not
182 // cycle from job.start_step() to job.end_step(), likely because the 184 // cycle from job.start_step() to job.end_step(), likely because the
183 // scheduler was forced to quit the job mid-way through. 185 // scheduler was forced to quit the job mid-way through.
184 bool FinishSyncSessionJob(SyncSessionJob* job, 186 bool FinishSyncSessionJob(SyncSessionJob* job,
185 bool exited_prematurely, 187 bool exited_prematurely,
186 sessions::SyncSession* session); 188 sessions::SyncSession* session);
187 189
188 // Helper to schedule retries of a failed configure or nudge job. 190 // Helper to schedule retries of a failed configure or nudge job.
189 void ScheduleNextSync(scoped_ptr<SyncSessionJob> finished_job, 191 void ScheduleNextSync(scoped_ptr<SyncSessionJob> finished_job,
190 sessions::SyncSession* session); 192 sessions::SyncSession* session);
191 193
192 // Helper to configure polling intervals. Used by Start and ScheduleNextSync. 194 // Helper to configure polling intervals. Used by Start and ScheduleNextSync.
193 void AdjustPolling(const SyncSessionJob* old_job); 195 void AdjustPolling(const SyncSessionJob* old_job);
194 196
197 // Resumes an existing wait interval, taking into account the time already
198 // spent waiting. Calling this funciton on a wait interval that is still
199 // active will have not effect, give or take a few small timing side-effects.
200 void ResumeWaiting();
201
195 // Helper to restart waiting with |wait_interval_|'s timer. 202 // Helper to restart waiting with |wait_interval_|'s timer.
196 void RestartWaiting(scoped_ptr<SyncSessionJob> job); 203 void RestartWaiting();
197 204
198 // Helper to ScheduleNextSync in case of consecutive sync errors. 205 // Helper to ScheduleNextSync in case of consecutive sync errors.
199 void HandleContinuationError(scoped_ptr<SyncSessionJob> old_job, 206 void HandleContinuationError(scoped_ptr<SyncSessionJob> old_job,
200 sessions::SyncSession* session); 207 sessions::SyncSession* session);
201 208
202 // Decide whether we should CONTINUE, SAVE or DROP the job. 209 // Decide whether we should CONTINUE, SAVE or DROP the job.
203 JobProcessDecision DecideOnJob(const SyncSessionJob& job, 210 JobProcessDecision DecideOnJob(const SyncSessionJob& job,
204 JobPriority priority); 211 JobPriority priority);
205 212
206 // If DecideOnJob decides that |job| should be SAVEd, this function will
207 // carry out the task of actually "saving" (or coalescing) the job.
208 void HandleSaveJobDecision(scoped_ptr<SyncSessionJob> job);
209
210 // Decide on whether to CONTINUE, SAVE or DROP the job when we are in 213 // Decide on whether to CONTINUE, SAVE or DROP the job when we are in
211 // backoff mode. 214 // backoff mode.
212 JobProcessDecision DecideWhileInWaitInterval(const SyncSessionJob& job, 215 JobProcessDecision DecideWhileInWaitInterval(const SyncSessionJob& job,
213 JobPriority priority); 216 JobPriority priority);
214 217
215 // 'Impl' here refers to real implementation of public functions, running on 218 // 'Impl' here refers to real implementation of public functions, running on
216 // |thread_|. 219 // |thread_|.
217 void StopImpl(const base::Closure& callback); 220 void StopImpl(const base::Closure& callback);
218 221
219 // If the scheduler's current state supports it, this will create a job based 222 // If the scheduler's current state supports it, this will create a job based
220 // on the passed in parameters and coalesce it with any other pending jobs, 223 // on the passed in parameters and coalesce it with any other pending jobs,
221 // then post a delayed task to run it. It may also choose to drop the job or 224 // then post a delayed task to run it. It may also choose to drop the job or
222 // save it for later, depending on the scheduler's current state. 225 // save it for later, depending on the scheduler's current state.
223 void ScheduleNudgeImpl( 226 void ScheduleNudgeImpl(
224 const base::TimeDelta& delay, 227 const base::TimeDelta& delay,
225 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, 228 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source,
226 const ModelTypeInvalidationMap& invalidation_map, 229 const ModelTypeInvalidationMap& invalidation_map,
227 const tracked_objects::Location& nudge_location); 230 const tracked_objects::Location& nudge_location);
228 231
229 // Returns true if the client is currently in exponential backoff. 232 // Returns true if the client is currently in exponential backoff.
230 bool IsBackingOff() const; 233 bool IsBackingOff() const;
231 234
232 // Helper to signal all listeners registered with |session_context_|. 235 // Helper to signal all listeners registered with |session_context_|.
233 void Notify(SyncEngineEvent::EventCause cause); 236 void Notify(SyncEngineEvent::EventCause cause);
234 237
235 // Helper to signal listeners about changed retry time 238 // Helper to signal listeners about changed retry time
236 void NotifyRetryTime(base::Time retry_time); 239 void NotifyRetryTime(base::Time retry_time);
237 240
238 // Callback to change backoff state. |to_be_canary| in both cases is the job 241 // Looks for pending work and, if it finds any, run this work at "canary"
239 // that should be granted canary privileges. Note: it is possible that the 242 // priority.
240 // job that gets scheduled when this callback is scheduled is different from 243 void TryCanaryJob();
241 // the job that will actually get executed, because other jobs may have been
242 // scheduled while we were waiting for the callback.
243 void DoCanaryJob(scoped_ptr<SyncSessionJob> to_be_canary);
244 void Unthrottle(scoped_ptr<SyncSessionJob> to_be_canary);
245 244
246 // Returns a pending job that has potential to run given the state of the 245 // Transitions out of the THROTTLED WaitInterval then calls TryCanaryJob().
247 // scheduler, if it exists. Useful whenever an event occurs that may 246 void Unthrottle();
248 // change conditions that permit a job to run, such as re-establishing
249 // network connection, auth refresh, mode changes etc. Note that the returned
250 // job may have been scheduled to run at a later time, or may have been
251 // unscheduled. In the former case, this will result in abandoning the old
252 // job and effectively cancelling it.
253 scoped_ptr<SyncSessionJob> TakePendingJobForCurrentMode();
254 247
255 // Called when the root cause of the current connection error is fixed. 248 // Called when the root cause of the current connection error is fixed.
256 void OnServerConnectionErrorFixed(); 249 void OnServerConnectionErrorFixed();
257 250
258 // Creates a session for a poll and performs the sync. 251 // Creates a session for a poll and performs the sync.
259 void PollTimerCallback(); 252 void PollTimerCallback();
260 253
261 // Called once the first time thread_ is started to broadcast an initial 254 // Called once the first time thread_ is started to broadcast an initial
262 // session snapshot containing data like initial_sync_ended. Important when 255 // session snapshot containing data like initial_sync_ended. Important when
263 // the client starts up and does not need to perform an initial sync. 256 // the client starts up and does not need to perform an initial sync.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 290
298 // Server-tweakable sessions commit delay. 291 // Server-tweakable sessions commit delay.
299 base::TimeDelta sessions_commit_delay_; 292 base::TimeDelta sessions_commit_delay_;
300 293
301 // Periodic timer for polling. See AdjustPolling. 294 // Periodic timer for polling. See AdjustPolling.
302 base::RepeatingTimer<SyncSchedulerImpl> poll_timer_; 295 base::RepeatingTimer<SyncSchedulerImpl> poll_timer_;
303 296
304 // The mode of operation. 297 // The mode of operation.
305 Mode mode_; 298 Mode mode_;
306 299
307 // Tracks (does not own) in-flight nudges (scheduled or unscheduled),
308 // so we can coalesce. NULL if there is no pending nudge.
309 SyncSessionJob* pending_nudge_;
310
311 // There are certain situations where we want to remember a nudge, but
312 // there is no well defined moment in time in the future when that nudge
313 // should run, e.g. if it requires a mode switch or updated auth credentials.
314 // This member will own NUDGE jobs in those cases, until an external event
315 // (mode switch or fixed auth) occurs to trigger a retry. Should be treated
316 // as opaque / not interacted with (i.e. we could build a wrapper to
317 // hide the type, but that's probably overkill).
318 scoped_ptr<SyncSessionJob> unscheduled_nudge_storage_;
319
320 // Current wait state. Null if we're not in backoff and not throttled. 300 // Current wait state. Null if we're not in backoff and not throttled.
321 scoped_ptr<WaitInterval> wait_interval_; 301 scoped_ptr<WaitInterval> wait_interval_;
322 302
323 scoped_ptr<BackoffDelayProvider> delay_provider_; 303 scoped_ptr<BackoffDelayProvider> delay_provider_;
324 304
325 // We allow at most one PostedTask to be pending at one time. This is it. 305 // We allow at most one PostedTask to be pending at one time. This is it.
326 // We will cancel this task before starting a new one. 306 // We will cancel this task before starting a new one.
327 base::CancelableClosure pending_wakeup_; 307 base::CancelableClosure pending_wakeup_;
328 308
309 // Pending configure job storage. Note that
310 // (mode_ != CONFIGURATION_MODE) \implies !pending_configure_job_.
311 scoped_ptr<SyncSessionJob> pending_configure_job_;
tim (not reviewing) 2013/04/04 00:22:11 Why does this belong here? Unless I'm mistaken thi
rlarocque 2013/04/04 00:59:48 I'm not that worried about it. We have plenty of
tim (not reviewing) 2013/04/04 18:07:30 Ok. A small concern I have is as the need to add n
312
313 // Pending nudge job storage. These jobs can exist in CONFIGURATION_MODE, but
314 // they will be run only in NORMAL_MODE.
315 scoped_ptr<SyncSessionJob> pending_nudge_job_;
316
329 // Invoked to run through the sync cycle. 317 // Invoked to run through the sync cycle.
330 scoped_ptr<Syncer> syncer_; 318 scoped_ptr<Syncer> syncer_;
331 319
332 sessions::SyncSessionContext* session_context_; 320 sessions::SyncSessionContext* session_context_;
333 321
334 // A map tracking LOCAL NudgeSource invocations of ScheduleNudge* APIs, 322 // A map tracking LOCAL NudgeSource invocations of ScheduleNudge* APIs,
335 // organized by datatype. Each datatype that was part of the types requested 323 // organized by datatype. Each datatype that was part of the types requested
336 // in the call will have its TimeTicks value updated. 324 // in the call will have its TimeTicks value updated.
337 typedef std::map<ModelType, base::TimeTicks> ModelTypeTimeMap; 325 typedef std::map<ModelType, base::TimeTicks> ModelTypeTimeMap;
338 ModelTypeTimeMap last_local_nudges_by_model_type_; 326 ModelTypeTimeMap last_local_nudges_by_model_type_;
339 327
340 // Used as an "anti-reentrancy defensive assertion". 328 // Used as an "anti-reentrancy defensive assertion".
341 // While true, it is illegal for any new scheduling activity to take place. 329 // While true, it is illegal for any new scheduling activity to take place.
342 // Ensures that higher layers don't break this law in response to events that 330 // Ensures that higher layers don't break this law in response to events that
343 // take place during a sync cycle. We call this out because such violations 331 // take place during a sync cycle. We call this out because such violations
344 // could result in tight sync loops hitting sync servers. 332 // could result in tight sync loops hitting sync servers.
345 bool no_scheduling_allowed_; 333 bool no_scheduling_allowed_;
346 334
347 DISALLOW_COPY_AND_ASSIGN(SyncSchedulerImpl); 335 DISALLOW_COPY_AND_ASSIGN(SyncSchedulerImpl);
348 }; 336 };
349 337
350 } // namespace syncer 338 } // namespace syncer
351 339
352 #endif // SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_ 340 #endif // SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_
OLDNEW
« no previous file with comments | « no previous file | sync/engine/sync_scheduler_impl.cc » ('j') | sync/engine/sync_scheduler_impl.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698