OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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_ |
OLD | NEW |