| OLD | NEW |
| 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 // A class to schedule syncer tasks intelligently. | 5 #ifndef SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_ |
| 6 #ifndef SYNC_ENGINE_SYNC_SCHEDULER_H_ | 6 #define SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_ |
| 7 #define SYNC_ENGINE_SYNC_SCHEDULER_H_ | |
| 8 | 7 |
| 9 #include <string> | 8 #include <string> |
| 10 | 9 |
| 11 #include "base/callback.h" | 10 #include "base/callback.h" |
| 12 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 13 #include "base/gtest_prod_util.h" | 12 #include "base/gtest_prod_util.h" |
| 14 #include "base/memory/linked_ptr.h" | 13 #include "base/memory/linked_ptr.h" |
| 15 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
| 17 #include "base/observer_list.h" | 16 #include "base/observer_list.h" |
| 18 #include "base/time.h" | 17 #include "base/time.h" |
| 19 #include "base/timer.h" | 18 #include "base/timer.h" |
| 20 #include "sync/engine/net/server_connection_manager.h" | 19 #include "sync/engine/net/server_connection_manager.h" |
| 21 #include "sync/engine/nudge_source.h" | 20 #include "sync/engine/nudge_source.h" |
| 21 #include "sync/engine/sync_scheduler.h" |
| 22 #include "sync/engine/syncer.h" | 22 #include "sync/engine/syncer.h" |
| 23 #include "sync/internal_api/public/base/model_type_payload_map.h" | 23 #include "sync/internal_api/public/base/model_type_payload_map.h" |
| 24 #include "sync/internal_api/public/engine/polling_constants.h" | 24 #include "sync/internal_api/public/engine/polling_constants.h" |
| 25 #include "sync/internal_api/public/util/weak_handle.h" | 25 #include "sync/internal_api/public/util/weak_handle.h" |
| 26 #include "sync/sessions/sync_session.h" | 26 #include "sync/sessions/sync_session.h" |
| 27 #include "sync/sessions/sync_session_context.h" | 27 #include "sync/sessions/sync_session_context.h" |
| 28 | 28 |
| 29 class MessageLoop; | |
| 30 | |
| 31 namespace tracked_objects { | |
| 32 class Location; | |
| 33 } // namespace tracked_objects | |
| 34 | |
| 35 namespace syncer { | 29 namespace syncer { |
| 36 | 30 |
| 37 struct ServerConnectionEvent; | 31 class SyncSchedulerImpl : public SyncScheduler { |
| 38 | |
| 39 struct ConfigurationParams { | |
| 40 enum KeystoreKeyStatus { | |
| 41 KEYSTORE_KEY_UNNECESSARY, | |
| 42 KEYSTORE_KEY_NEEDED | |
| 43 }; | |
| 44 ConfigurationParams(); | |
| 45 ConfigurationParams( | |
| 46 const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, | |
| 47 const syncer::ModelTypeSet& types_to_download, | |
| 48 const syncer::ModelSafeRoutingInfo& routing_info, | |
| 49 KeystoreKeyStatus keystore_key_status, | |
| 50 const base::Closure& ready_task); | |
| 51 ~ConfigurationParams(); | |
| 52 | |
| 53 // Source for the configuration. | |
| 54 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source; | |
| 55 // The types that should be downloaded. | |
| 56 syncer::ModelTypeSet types_to_download; | |
| 57 // The new routing info (superset of types to be downloaded). | |
| 58 ModelSafeRoutingInfo routing_info; | |
| 59 // Whether we need to perform a GetKey command. | |
| 60 KeystoreKeyStatus keystore_key_status; | |
| 61 // Callback to invoke on configuration completion. | |
| 62 base::Closure ready_task; | |
| 63 }; | |
| 64 | |
| 65 class SyncScheduler : public sessions::SyncSession::Delegate { | |
| 66 public: | 32 public: |
| 67 enum Mode { | |
| 68 // In this mode, the thread only performs configuration tasks. This is | |
| 69 // designed to make the case where we want to download updates for a | |
| 70 // specific type only, and not continue syncing until we are moved into | |
| 71 // normal mode. | |
| 72 CONFIGURATION_MODE, | |
| 73 // Resumes polling and allows nudges, drops configuration tasks. Runs | |
| 74 // through entire sync cycle. | |
| 75 NORMAL_MODE, | |
| 76 }; | |
| 77 | |
| 78 // All methods of SyncScheduler must be called on the same thread | |
| 79 // (except for RequestEarlyExit()). | |
| 80 | |
| 81 // |name| is a display string to identify the syncer thread. Takes | 33 // |name| is a display string to identify the syncer thread. Takes |
| 82 // |ownership of |syncer|. | 34 // |ownership of |syncer|. |
| 83 SyncScheduler(const std::string& name, | 35 SyncSchedulerImpl(const std::string& name, |
| 84 sessions::SyncSessionContext* context, Syncer* syncer); | 36 sessions::SyncSessionContext* context, Syncer* syncer); |
| 85 | 37 |
| 86 // Calls Stop(). | 38 // Calls Stop(). |
| 87 virtual ~SyncScheduler(); | 39 virtual ~SyncSchedulerImpl(); |
| 88 | 40 |
| 89 // Start the scheduler with the given mode. If the scheduler is | 41 virtual void Start(Mode mode) OVERRIDE; |
| 90 // already started, switch to the given mode, although some | 42 virtual bool ScheduleConfiguration( |
| 91 // scheduled tasks from the old mode may still run. | 43 const ConfigurationParams& params) OVERRIDE; |
| 92 virtual void Start(Mode mode); | 44 virtual void RequestStop(const base::Closure& callback) OVERRIDE; |
| 93 | 45 virtual void ScheduleNudgeAsync( |
| 94 // Schedules the configuration task specified by |params|. Returns true if | 46 const base::TimeDelta& delay, |
| 95 // the configuration task executed immediately, false if it had to be | 47 NudgeSource source, |
| 96 // scheduled for a later attempt. |params.ready_task| is invoked whenever the | 48 syncer::ModelTypeSet types, |
| 97 // configuration task executes. | 49 const tracked_objects::Location& nudge_location) OVERRIDE; |
| 98 // Note: must already be in CONFIGURATION mode. | 50 virtual void ScheduleNudgeWithPayloadsAsync( |
| 99 virtual bool ScheduleConfiguration(const ConfigurationParams& params); | |
| 100 | |
| 101 // Request that any running syncer task stop as soon as possible and | |
| 102 // cancel all scheduled tasks. This function can be called from any thread, | |
| 103 // and should in fact be called from a thread that isn't the sync loop to | |
| 104 // allow preempting ongoing sync cycles. | |
| 105 // Invokes |callback| from the sync loop once syncer is idle and all tasks | |
| 106 // are cancelled. | |
| 107 void RequestStop(const base::Closure& callback); | |
| 108 | |
| 109 // The meat and potatoes. Both of these methods will post a delayed task | |
| 110 // to attempt the actual nudge (see ScheduleNudgeImpl). | |
| 111 void ScheduleNudgeAsync(const base::TimeDelta& delay, NudgeSource source, | |
| 112 syncer::ModelTypeSet types, | |
| 113 const tracked_objects::Location& nudge_location); | |
| 114 void ScheduleNudgeWithPayloadsAsync( | |
| 115 const base::TimeDelta& delay, NudgeSource source, | 51 const base::TimeDelta& delay, NudgeSource source, |
| 116 const syncer::ModelTypePayloadMap& types_with_payloads, | 52 const syncer::ModelTypePayloadMap& types_with_payloads, |
| 117 const tracked_objects::Location& nudge_location); | 53 const tracked_objects::Location& nudge_location) OVERRIDE; |
| 54 virtual void SetNotificationsEnabled(bool notifications_enabled) OVERRIDE; |
| 118 | 55 |
| 119 void CleanupDisabledTypes(); | 56 virtual base::TimeDelta GetSessionsCommitDelay() const OVERRIDE; |
| 120 | 57 |
| 121 // Change status of notifications in the SyncSessionContext. | 58 virtual void OnCredentialsUpdated() OVERRIDE; |
| 122 void set_notifications_enabled(bool notifications_enabled); | 59 virtual void OnConnectionStatusChange() OVERRIDE; |
| 123 | |
| 124 base::TimeDelta sessions_commit_delay() const; | |
| 125 | |
| 126 // DDOS avoidance function. Calculates how long we should wait before trying | |
| 127 // again after a failed sync attempt, where the last delay was |base_delay|. | |
| 128 // TODO(tim): Look at URLRequestThrottlerEntryInterface. | |
| 129 static base::TimeDelta GetRecommendedDelay(const base::TimeDelta& base_delay); | |
| 130 | |
| 131 // Called when credentials are updated by the user. | |
| 132 void OnCredentialsUpdated(); | |
| 133 | |
| 134 // Called when the network layer detects a connection status change. | |
| 135 void OnConnectionStatusChange(); | |
| 136 | 60 |
| 137 // SyncSession::Delegate implementation. | 61 // SyncSession::Delegate implementation. |
| 138 virtual void OnSilencedUntil( | 62 virtual void OnSilencedUntil( |
| 139 const base::TimeTicks& silenced_until) OVERRIDE; | 63 const base::TimeTicks& silenced_until) OVERRIDE; |
| 140 virtual bool IsSyncingCurrentlySilenced() OVERRIDE; | 64 virtual bool IsSyncingCurrentlySilenced() OVERRIDE; |
| 141 virtual void OnReceivedShortPollIntervalUpdate( | 65 virtual void OnReceivedShortPollIntervalUpdate( |
| 142 const base::TimeDelta& new_interval) OVERRIDE; | 66 const base::TimeDelta& new_interval) OVERRIDE; |
| 143 virtual void OnReceivedLongPollIntervalUpdate( | 67 virtual void OnReceivedLongPollIntervalUpdate( |
| 144 const base::TimeDelta& new_interval) OVERRIDE; | 68 const base::TimeDelta& new_interval) OVERRIDE; |
| 145 virtual void OnReceivedSessionsCommitDelay( | 69 virtual void OnReceivedSessionsCommitDelay( |
| 146 const base::TimeDelta& new_delay) OVERRIDE; | 70 const base::TimeDelta& new_delay) OVERRIDE; |
| 147 virtual void OnShouldStopSyncingPermanently() OVERRIDE; | 71 virtual void OnShouldStopSyncingPermanently() OVERRIDE; |
| 148 virtual void OnSyncProtocolError( | 72 virtual void OnSyncProtocolError( |
| 149 const sessions::SyncSessionSnapshot& snapshot) OVERRIDE; | 73 const sessions::SyncSessionSnapshot& snapshot) OVERRIDE; |
| 150 | 74 |
| 75 // DDOS avoidance function. Calculates how long we should wait before trying |
| 76 // again after a failed sync attempt, where the last delay was |base_delay|. |
| 77 // TODO(tim): Look at URLRequestThrottlerEntryInterface. |
| 78 static base::TimeDelta GetRecommendedDelay(const base::TimeDelta& base_delay); |
| 79 |
| 151 private: | 80 private: |
| 152 enum JobProcessDecision { | 81 enum JobProcessDecision { |
| 153 // Indicates we should continue with the current job. | 82 // Indicates we should continue with the current job. |
| 154 CONTINUE, | 83 CONTINUE, |
| 155 // Indicates that we should save it to be processed later. | 84 // Indicates that we should save it to be processed later. |
| 156 SAVE, | 85 SAVE, |
| 157 // Indicates we should drop this job. | 86 // Indicates we should drop this job. |
| 158 DROP, | 87 DROP, |
| 159 }; | 88 }; |
| 160 | 89 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 WaitInterval(Mode mode, base::TimeDelta length); | 176 WaitInterval(Mode mode, base::TimeDelta length); |
| 248 | 177 |
| 249 static const char* GetModeString(Mode mode); | 178 static const char* GetModeString(Mode mode); |
| 250 | 179 |
| 251 Mode mode; | 180 Mode mode; |
| 252 | 181 |
| 253 // This bool is set to true if we have observed a nudge during this | 182 // This bool is set to true if we have observed a nudge during this |
| 254 // interval and mode == EXPONENTIAL_BACKOFF. | 183 // interval and mode == EXPONENTIAL_BACKOFF. |
| 255 bool had_nudge; | 184 bool had_nudge; |
| 256 base::TimeDelta length; | 185 base::TimeDelta length; |
| 257 base::OneShotTimer<SyncScheduler> timer; | 186 base::OneShotTimer<SyncSchedulerImpl> timer; |
| 258 | 187 |
| 259 // Configure jobs are saved only when backing off or throttling. So we | 188 // Configure jobs are saved only when backing off or throttling. So we |
| 260 // expose the pointer here. | 189 // expose the pointer here. |
| 261 scoped_ptr<SyncSessionJob> pending_configure_job; | 190 scoped_ptr<SyncSessionJob> pending_configure_job; |
| 262 }; | 191 }; |
| 263 | 192 |
| 264 static const char* GetModeString(Mode mode); | 193 static const char* GetModeString(Mode mode); |
| 265 | 194 |
| 266 static const char* GetDecisionString(JobProcessDecision decision); | 195 static const char* GetDecisionString(JobProcessDecision decision); |
| 267 | 196 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 void UpdateServerConnectionManagerStatus( | 292 void UpdateServerConnectionManagerStatus( |
| 364 HttpResponse::ServerConnectionCode code); | 293 HttpResponse::ServerConnectionCode code); |
| 365 | 294 |
| 366 // Called once the first time thread_ is started to broadcast an initial | 295 // Called once the first time thread_ is started to broadcast an initial |
| 367 // session snapshot containing data like initial_sync_ended. Important when | 296 // session snapshot containing data like initial_sync_ended. Important when |
| 368 // the client starts up and does not need to perform an initial sync. | 297 // the client starts up and does not need to perform an initial sync. |
| 369 void SendInitialSnapshot(); | 298 void SendInitialSnapshot(); |
| 370 | 299 |
| 371 virtual void OnActionableError(const sessions::SyncSessionSnapshot& snapshot); | 300 virtual void OnActionableError(const sessions::SyncSessionSnapshot& snapshot); |
| 372 | 301 |
| 373 base::WeakPtrFactory<SyncScheduler> weak_ptr_factory_; | 302 base::WeakPtrFactory<SyncSchedulerImpl> weak_ptr_factory_; |
| 374 | 303 |
| 375 // A second factory specially for weak_handle_this_, to allow the handle | 304 // A second factory specially for weak_handle_this_, to allow the handle |
| 376 // to be const and alleviate threading concerns. | 305 // to be const and alleviate threading concerns. |
| 377 base::WeakPtrFactory<SyncScheduler> weak_ptr_factory_for_weak_handle_; | 306 base::WeakPtrFactory<SyncSchedulerImpl> weak_ptr_factory_for_weak_handle_; |
| 378 | 307 |
| 379 // For certain methods that need to worry about X-thread posting. | 308 // For certain methods that need to worry about X-thread posting. |
| 380 const WeakHandle<SyncScheduler> weak_handle_this_; | 309 const WeakHandle<SyncSchedulerImpl> weak_handle_this_; |
| 381 | 310 |
| 382 // Used for logging. | 311 // Used for logging. |
| 383 const std::string name_; | 312 const std::string name_; |
| 384 | 313 |
| 385 // The message loop this object is on. Almost all methods have to | 314 // The message loop this object is on. Almost all methods have to |
| 386 // be called on this thread. | 315 // be called on this thread. |
| 387 MessageLoop* const sync_loop_; | 316 MessageLoop* const sync_loop_; |
| 388 | 317 |
| 389 // Set in Start(), unset in Stop(). | 318 // Set in Start(), unset in Stop(). |
| 390 bool started_; | 319 bool started_; |
| 391 | 320 |
| 392 // Modifiable versions of kDefaultLongPollIntervalSeconds which can be | 321 // Modifiable versions of kDefaultLongPollIntervalSeconds which can be |
| 393 // updated by the server. | 322 // updated by the server. |
| 394 base::TimeDelta syncer_short_poll_interval_seconds_; | 323 base::TimeDelta syncer_short_poll_interval_seconds_; |
| 395 base::TimeDelta syncer_long_poll_interval_seconds_; | 324 base::TimeDelta syncer_long_poll_interval_seconds_; |
| 396 | 325 |
| 397 // Server-tweakable sessions commit delay. | 326 // Server-tweakable sessions commit delay. |
| 398 base::TimeDelta sessions_commit_delay_; | 327 base::TimeDelta sessions_commit_delay_; |
| 399 | 328 |
| 400 // Periodic timer for polling. See AdjustPolling. | 329 // Periodic timer for polling. See AdjustPolling. |
| 401 base::RepeatingTimer<SyncScheduler> poll_timer_; | 330 base::RepeatingTimer<SyncSchedulerImpl> poll_timer_; |
| 402 | 331 |
| 403 // The mode of operation. | 332 // The mode of operation. |
| 404 Mode mode_; | 333 Mode mode_; |
| 405 | 334 |
| 406 // TODO(tim): Bug 26339. This needs to track more than just time I think, | 335 // TODO(tim): Bug 26339. This needs to track more than just time I think, |
| 407 // since the nudges could be for different types. Current impl doesn't care. | 336 // since the nudges could be for different types. Current impl doesn't care. |
| 408 base::TimeTicks last_sync_session_end_time_; | 337 base::TimeTicks last_sync_session_end_time_; |
| 409 | 338 |
| 410 // The latest connection code we got while trying to connect. | 339 // The latest connection code we got while trying to connect. |
| 411 HttpResponse::ServerConnectionCode connection_code_; | 340 HttpResponse::ServerConnectionCode connection_code_; |
| 412 | 341 |
| 413 // Tracks in-flight nudges so we can coalesce. | 342 // Tracks in-flight nudges so we can coalesce. |
| 414 scoped_ptr<SyncSessionJob> pending_nudge_; | 343 scoped_ptr<SyncSessionJob> pending_nudge_; |
| 415 | 344 |
| 416 // Current wait state. Null if we're not in backoff and not throttled. | 345 // Current wait state. Null if we're not in backoff and not throttled. |
| 417 scoped_ptr<WaitInterval> wait_interval_; | 346 scoped_ptr<WaitInterval> wait_interval_; |
| 418 | 347 |
| 419 scoped_ptr<DelayProvider> delay_provider_; | 348 scoped_ptr<DelayProvider> delay_provider_; |
| 420 | 349 |
| 421 // Invoked to run through the sync cycle. | 350 // Invoked to run through the sync cycle. |
| 422 scoped_ptr<Syncer> syncer_; | 351 scoped_ptr<Syncer> syncer_; |
| 423 | 352 |
| 424 sessions::SyncSessionContext *session_context_; | 353 sessions::SyncSessionContext *session_context_; |
| 425 | 354 |
| 426 DISALLOW_COPY_AND_ASSIGN(SyncScheduler); | 355 DISALLOW_COPY_AND_ASSIGN(SyncSchedulerImpl); |
| 427 }; | 356 }; |
| 428 | 357 |
| 429 } // namespace syncer | 358 } // namespace syncer |
| 430 | 359 |
| 431 #endif // SYNC_ENGINE_SYNC_SCHEDULER_H_ | 360 #endif // SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_ |
| OLD | NEW |