| OLD | NEW |
| 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 Loading... |
| 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 |
| 146 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, |
| 147 DropNudgeWhileExponentialBackOff); |
| 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 ContinueCanaryJobConfig); |
| 161 FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, |
| 162 ContinueNudgeWhileExponentialBackOff); |
| 126 | 163 |
| 127 // A component used to get time delays associated with exponential backoff. | 164 // A component used to get time delays associated with exponential backoff. |
| 128 // Encapsulated into a class to facilitate testing. | 165 // Encapsulated into a class to facilitate testing. |
| 129 class DelayProvider { | 166 class DelayProvider { |
| 130 public: | 167 public: |
| 131 DelayProvider(); | 168 DelayProvider(); |
| 132 virtual base::TimeDelta GetDelay(const base::TimeDelta& last_delay); | 169 virtual base::TimeDelta GetDelay(const base::TimeDelta& last_delay); |
| 133 virtual ~DelayProvider(); | 170 virtual ~DelayProvider(); |
| 134 private: | 171 private: |
| 135 DISALLOW_COPY_AND_ASSIGN(DelayProvider); | 172 DISALLOW_COPY_AND_ASSIGN(DelayProvider); |
| 136 }; | 173 }; |
| 137 | 174 |
| 175 struct WaitInterval { |
| 176 enum Mode { |
| 177 // A wait interval whose duration has been affected by exponential |
| 178 // backoff. |
| 179 // EXPONENTIAL_BACKOFF intervals are nudge-rate limited to 1 per interval. |
| 180 EXPONENTIAL_BACKOFF, |
| 181 // A server-initiated throttled interval. We do not allow any syncing |
| 182 // during such an interval. |
| 183 THROTTLED, |
| 184 }; |
| 185 WaitInterval(); |
| 186 ~WaitInterval(); |
| 187 |
| 188 Mode mode; |
| 189 |
| 190 // This bool is set to true if we have observed a nudge during this |
| 191 // interval and mode == EXPONENTIAL_BACKOFF. |
| 192 bool had_nudge; |
| 193 base::TimeDelta length; |
| 194 base::OneShotTimer<SyncerThread> timer; |
| 195 |
| 196 // Configure jobs are saved only when backing off or throttling. So we |
| 197 // expose the pointer here. |
| 198 scoped_ptr<SyncSessionJob> pending_configure_job; |
| 199 WaitInterval(Mode mode, base::TimeDelta length); |
| 200 }; |
| 201 |
| 138 // Helper to assemble a job and post a delayed task to sync. | 202 // Helper to assemble a job and post a delayed task to sync. |
| 139 void ScheduleSyncSessionJob(const base::TimeDelta& delay, | 203 void ScheduleSyncSessionJob( |
| 140 SyncSessionJobPurpose purpose, | 204 const base::TimeDelta& delay, |
| 141 sessions::SyncSession* session, | 205 SyncSessionJob::SyncSessionJobPurpose purpose, |
| 142 const tracked_objects::Location& nudge_location); | 206 sessions::SyncSession* session, |
| 207 const tracked_objects::Location& nudge_location); |
| 143 | 208 |
| 144 // Invoke the Syncer to perform a sync. | 209 // Invoke the Syncer to perform a sync. |
| 145 void DoSyncSessionJob(const SyncSessionJob& job); | 210 void DoSyncSessionJob(const SyncSessionJob& job); |
| 146 | 211 |
| 147 // Called after the Syncer has performed the sync represented by |job|, to | 212 // Called after the Syncer has performed the sync represented by |job|, to |
| 148 // reset our state. | 213 // reset our state. |
| 149 void FinishSyncSessionJob(const SyncSessionJob& job); | 214 void FinishSyncSessionJob(const SyncSessionJob& job); |
| 150 | 215 |
| 151 // Record important state that might be needed in future syncs, such as which | 216 // Record important state that might be needed in future syncs, such as which |
| 152 // data types may require cleanup. | 217 // data types may require cleanup. |
| 153 void UpdateCarryoverSessionState(const SyncSessionJob& old_job); | 218 void UpdateCarryoverSessionState(const SyncSessionJob& old_job); |
| 154 | 219 |
| 155 // Helper to FinishSyncSessionJob to schedule the next sync operation. | 220 // Helper to FinishSyncSessionJob to schedule the next sync operation. |
| 156 void ScheduleNextSync(const SyncSessionJob& old_job); | 221 void ScheduleNextSync(const SyncSessionJob& old_job); |
| 157 | 222 |
| 158 // Helper to configure polling intervals. Used by Start and ScheduleNextSync. | 223 // Helper to configure polling intervals. Used by Start and ScheduleNextSync. |
| 159 void AdjustPolling(const SyncSessionJob* old_job); | 224 void AdjustPolling(const SyncSessionJob* old_job); |
| 160 | 225 |
| 161 // Helper to ScheduleNextSync in case of consecutive sync errors. | 226 // Helper to ScheduleNextSync in case of consecutive sync errors. |
| 162 void HandleConsecutiveContinuationError(const SyncSessionJob& old_job); | 227 void HandleConsecutiveContinuationError(const SyncSessionJob& old_job); |
| 163 | 228 |
| 164 // Determines if it is legal to run a sync job for |purpose| at | 229 // Determines if it is legal to run |job| by checking current |
| 165 // |scheduled_start|. This checks current operational mode, backoff or | 230 // operational mode, backoff or throttling, freshness |
| 166 // throttling, freshness (so we don't make redundant syncs), and connection. | 231 // (so we don't make redundant syncs), and connection. |
| 167 bool ShouldRunJob(SyncSessionJobPurpose purpose, | 232 bool ShouldRunJob(const SyncSessionJob& job); |
| 168 const base::TimeTicks& scheduled_start); | 233 |
| 234 // Decide whether we should CONTINUE, SAVE or DROP the job. |
| 235 JobProcessDecision DecideOnJob(const SyncSessionJob& job); |
| 236 |
| 237 // Decide on whether to CONTINUE, SAVE or DROP the job when we are in |
| 238 // backoff mode. |
| 239 JobProcessDecision DecideWhileInWaitInterval(const SyncSessionJob& job); |
| 240 |
| 241 // Saves the job for future execution. Note: It drops all the poll jobs. |
| 242 void SaveJob(const SyncSessionJob& job); |
| 243 |
| 244 // Coalesces the current job with the pending nudge. |
| 245 void InitOrCoalescePendingJob(const SyncSessionJob& job); |
| 169 | 246 |
| 170 // 'Impl' here refers to real implementation of public functions, running on | 247 // 'Impl' here refers to real implementation of public functions, running on |
| 171 // |thread_|. | 248 // |thread_|. |
| 172 void StartImpl(Mode mode, linked_ptr<ModeChangeCallback> callback); | 249 void StartImpl(Mode mode, linked_ptr<ModeChangeCallback> callback); |
| 173 void ScheduleNudgeImpl( | 250 void ScheduleNudgeImpl( |
| 174 const base::TimeDelta& delay, | 251 const base::TimeDelta& delay, |
| 175 NudgeSource source, | 252 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, |
| 176 const syncable::ModelTypePayloadMap& types_with_payloads, | 253 const syncable::ModelTypePayloadMap& types_with_payloads, |
| 177 const tracked_objects::Location& nudge_location); | 254 bool is_canary_job, const tracked_objects::Location& nudge_location); |
| 178 void ScheduleConfigImpl(const ModelSafeRoutingInfo& routing_info, | 255 void ScheduleConfigImpl(const ModelSafeRoutingInfo& routing_info, |
| 179 const std::vector<ModelSafeWorker*>& workers); | 256 const std::vector<ModelSafeWorker*>& workers, |
| 257 const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source); |
| 180 void ScheduleClearUserDataImpl(); | 258 void ScheduleClearUserDataImpl(); |
| 181 | 259 |
| 182 // Returns true if the client is currently in exponential backoff. | 260 // Returns true if the client is currently in exponential backoff. |
| 183 bool IsBackingOff() const; | 261 bool IsBackingOff() const; |
| 184 | 262 |
| 185 // Helper to signal all listeners registered with |session_context_|. | 263 // Helper to signal all listeners registered with |session_context_|. |
| 186 void Notify(SyncEngineEvent::EventCause cause); | 264 void Notify(SyncEngineEvent::EventCause cause); |
| 187 | 265 |
| 188 // Callback to change backoff state. | 266 // Callback to change backoff state. |
| 189 void DoCanaryJob(); | 267 void DoCanaryJob(); |
| 190 void Unthrottle(); | 268 void Unthrottle(); |
| 191 | 269 |
| 270 // Executes the pending job. Called whenever an event occurs that may |
| 271 // change conditions permitting a job to run. Like when network connection is |
| 272 // re-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 Loading... |
| 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_ |
| OLD | NEW |