sync_scheduler_impl.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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
  3. // found in the LICENSE file.
  4. #ifndef COMPONENTS_SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_
  5. #define COMPONENTS_SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include "base/callback.h"
  10. #include "base/cancelable_callback.h"
  11. #include "base/compiler_specific.h"
  12. #include "base/gtest_prod_util.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "base/memory/weak_ptr.h"
  15. #include "base/sequence_checker.h"
  16. #include "base/time/time.h"
  17. #include "base/timer/timer.h"
  18. #include "components/sync/engine/cycle/nudge_tracker.h"
  19. #include "components/sync/engine/cycle/sync_cycle.h"
  20. #include "components/sync/engine/cycle/sync_cycle_context.h"
  21. #include "components/sync/engine/net/server_connection_manager.h"
  22. #include "components/sync/engine/polling_constants.h"
  23. #include "components/sync/engine/sync_scheduler.h"
  24. #include "components/sync/engine/syncer.h"
  25. namespace syncer {
  26. class BackoffDelayProvider;
  27. struct ModelNeutralState;
  28. class SyncSchedulerImpl : public SyncScheduler {
  29. public:
  30. // |name| is a display string to identify the syncer thread.
  31. SyncSchedulerImpl(const std::string& name,
  32. std::unique_ptr<BackoffDelayProvider> delay_provider,
  33. SyncCycleContext* context,
  34. std::unique_ptr<Syncer> syncer,
  35. bool ignore_auth_credentials);
  36. SyncSchedulerImpl(const SyncSchedulerImpl&) = delete;
  37. SyncSchedulerImpl& operator=(const SyncSchedulerImpl&) = delete;
  38. // Calls Stop().
  39. ~SyncSchedulerImpl() override;
  40. void Start(Mode mode, base::Time last_poll_time) override;
  41. void ScheduleConfiguration(sync_pb::SyncEnums::GetUpdatesOrigin origin,
  42. ModelTypeSet types_to_download,
  43. base::OnceClosure ready_task) override;
  44. void Stop() override;
  45. void ScheduleLocalNudge(ModelType type) override;
  46. void ScheduleLocalRefreshRequest(ModelTypeSet types) override;
  47. void ScheduleInvalidationNudge(
  48. ModelType type,
  49. std::unique_ptr<SyncInvalidation> invalidation) override;
  50. void ScheduleInitialSyncNudge(ModelType model_type) override;
  51. void SetNotificationsEnabled(bool notifications_enabled) override;
  52. void OnCredentialsUpdated() override;
  53. void OnConnectionStatusChange(network::mojom::ConnectionType type) override;
  54. // SyncCycle::Delegate implementation.
  55. void OnThrottled(const base::TimeDelta& throttle_duration) override;
  56. void OnTypesThrottled(ModelTypeSet types,
  57. const base::TimeDelta& throttle_duration) override;
  58. void OnTypesBackedOff(ModelTypeSet types) override;
  59. bool IsAnyThrottleOrBackoff() override;
  60. void OnReceivedPollIntervalUpdate(
  61. const base::TimeDelta& new_interval) override;
  62. void OnReceivedCustomNudgeDelays(
  63. const std::map<ModelType, base::TimeDelta>& nudge_delays) override;
  64. void OnReceivedClientInvalidationHintBufferSize(int size) override;
  65. void OnSyncProtocolError(
  66. const SyncProtocolError& sync_protocol_error) override;
  67. void OnReceivedGuRetryDelay(const base::TimeDelta& delay) override;
  68. void OnReceivedMigrationRequest(ModelTypeSet types) override;
  69. void OnReceivedQuotaParamsForExtensionTypes(
  70. absl::optional<int> max_tokens,
  71. absl::optional<base::TimeDelta> refill_interval,
  72. absl::optional<base::TimeDelta> depleted_quota_nudge_delay) override;
  73. bool IsGlobalThrottle() const;
  74. bool IsGlobalBackoff() const;
  75. // Reduces nudge delays for all types to a very short value and prevents their
  76. // further changing by the server. Used to speed up passing of integration
  77. // tests.
  78. void ForceShortNudgeDelayForTest();
  79. private:
  80. struct ConfigurationParams {
  81. ConfigurationParams(sync_pb::SyncEnums::GetUpdatesOrigin origin,
  82. ModelTypeSet types_to_download,
  83. base::OnceClosure ready_task);
  84. ~ConfigurationParams();
  85. ConfigurationParams(const ConfigurationParams&) = delete;
  86. ConfigurationParams& operator=(const ConfigurationParams&) = delete;
  87. const sync_pb::SyncEnums::GetUpdatesOrigin origin;
  88. const ModelTypeSet types_to_download;
  89. // Callback to invoke on configuration completion.
  90. base::OnceClosure ready_task;
  91. };
  92. enum JobPriority {
  93. // Non-canary jobs respect exponential backoff.
  94. NORMAL_PRIORITY,
  95. // Canary jobs bypass exponential backoff, so use with extreme caution.
  96. CANARY_PRIORITY
  97. };
  98. enum PollAdjustType {
  99. // Restart the poll interval.
  100. FORCE_RESET,
  101. // Restart the poll interval only if its length has changed.
  102. UPDATE_INTERVAL,
  103. };
  104. friend class SyncSchedulerImplTest;
  105. friend class SyncerTest;
  106. FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest, TransientPollFailure);
  107. FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest,
  108. ServerConnectionChangeDuringBackoff);
  109. FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest,
  110. ConnectionChangeCanaryPreemptedByNudge);
  111. FRIEND_TEST_ALL_PREFIXES(BackoffTriggersSyncSchedulerTest,
  112. FailGetEncryptionKey);
  113. FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest, SuccessfulRetry);
  114. FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest, FailedRetry);
  115. FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest, ReceiveNewRetryDelay);
  116. static const char* GetModeString(Mode mode);
  117. // Invoke the syncer to perform a nudge job.
  118. void DoNudgeSyncCycleJob(JobPriority priority);
  119. // Invoke the syncer to perform a configuration job.
  120. void DoConfigurationSyncCycleJob(JobPriority priority);
  121. // Helper function for Do{Nudge,Configuration,Poll}SyncCycleJob.
  122. void HandleSuccess();
  123. // Helper function for Do{Nudge,Configuration,Poll}SyncCycleJob.
  124. void HandleFailure(const ModelNeutralState& model_neutral_state);
  125. // Invoke the Syncer to perform a poll job.
  126. void DoPollSyncCycleJob();
  127. // Helper function to calculate poll interval.
  128. base::TimeDelta GetPollInterval();
  129. // Adjusts the poll timer to account for new poll interval, and possibly
  130. // resets the poll interval, depedning on the flag's value.
  131. void AdjustPolling(PollAdjustType type);
  132. // Helper to restart pending_wakeup_timer_.
  133. // This function need to be called in 3 conditions, backoff/throttling
  134. // happens, unbackoff/unthrottling happens and after |PerformDelayedNudge|
  135. // runs.
  136. // This function is for scheduling unbackoff/unthrottling jobs, and the
  137. // poriority is, global unbackoff/unthrottling job first, if there is no
  138. // global backoff/throttling, then try to schedule types
  139. // unbackoff/unthrottling job.
  140. void RestartWaiting();
  141. // Determines if we're allowed to contact the server right now.
  142. bool CanRunJobNow(JobPriority priority);
  143. // Determines if we're allowed to contact the server right now.
  144. bool CanRunNudgeJobNow(JobPriority priority);
  145. // If the scheduler's current state supports it, this will create a job based
  146. // on the passed in parameters and coalesce it with any other pending jobs,
  147. // then post a delayed task to run it. It may also choose to drop the job or
  148. // save it for later, depending on the scheduler's current state.
  149. void ScheduleNudgeImpl(const base::TimeDelta& delay);
  150. // Helper to signal listeners about changed retry time.
  151. void NotifyRetryTime(base::Time retry_time);
  152. // Helper to signal listeners about changed throttled or backed off types.
  153. void NotifyBlockedTypesChanged();
  154. // Looks for pending work and, if it finds any, run this work at "canary"
  155. // priority.
  156. void TryCanaryJob();
  157. // At the moment TrySyncCycleJob just posts call to TrySyncCycleJobImpl on
  158. // current thread. In the future it will request access token here.
  159. void TrySyncCycleJob();
  160. void TrySyncCycleJobImpl();
  161. // Transitions out of the THROTTLED WaitInterval then calls TryCanaryJob().
  162. // This function is for global throttling.
  163. void Unthrottle();
  164. // Called when a per-type throttling or backing off interval expires.
  165. void OnTypesUnblocked();
  166. // Runs a normal nudge job when the scheduled timer expires.
  167. void PerformDelayedNudge();
  168. // Attempts to exit EXPONENTIAL_BACKOFF by calling TryCanaryJob().
  169. // This function is for global backoff.
  170. void ExponentialBackoffRetry();
  171. // Called when the root cause of the current connection error is fixed.
  172. void OnServerConnectionErrorFixed();
  173. // Creates a cycle for a poll and performs the sync.
  174. void PollTimerCallback();
  175. // Creates a cycle for a retry and performs the sync.
  176. void RetryTimerCallback();
  177. // Returns the set of types that are enabled and not currently throttled and
  178. // backed off.
  179. ModelTypeSet GetEnabledAndUnblockedTypes();
  180. // Called as we are started to broadcast an initial cycle snapshot
  181. // containing data like initial_sync_ended. Important when the client starts
  182. // up and does not need to perform an initial sync.
  183. void SendInitialSnapshot();
  184. bool IsEarlierThanCurrentPendingJob(const base::TimeDelta& delay);
  185. // Computes the last poll time the system should assume on start-up.
  186. static base::Time ComputeLastPollOnStart(base::Time last_poll,
  187. base::TimeDelta poll_interval,
  188. base::Time now);
  189. // Used for logging.
  190. const std::string name_;
  191. // Set in Start(), unset in Stop().
  192. bool started_;
  193. // Modifiable versions of kDefaultPollIntervalSeconds which can be
  194. // updated by the server.
  195. base::TimeDelta syncer_poll_interval_seconds_;
  196. // Timer for polling. Restarted on each successful poll, and when entering
  197. // normal sync mode or exiting an error state. Not active in configuration
  198. // mode.
  199. base::OneShotTimer poll_timer_;
  200. // The mode of operation.
  201. Mode mode_;
  202. // Current wait state. Null if we're not in backoff and not throttled.
  203. std::unique_ptr<WaitInterval> wait_interval_;
  204. std::unique_ptr<BackoffDelayProvider> delay_provider_;
  205. // TODO(gangwu): http://crbug.com/714868 too many timers in this class, try to
  206. // reduce them.
  207. // The event that will wake us up.
  208. // When the whole client got throttling or backoff, we will delay this timer
  209. // as well.
  210. base::OneShotTimer pending_wakeup_timer_;
  211. // Storage for variables related to an in-progress configure request. Note
  212. // that (mode_ != CONFIGURATION_MODE) \implies !pending_configure_params_.
  213. std::unique_ptr<ConfigurationParams> pending_configure_params_;
  214. // Keeps track of work that the syncer needs to handle.
  215. NudgeTracker nudge_tracker_;
  216. // Invoked to run through the sync cycle.
  217. const std::unique_ptr<Syncer> syncer_;
  218. raw_ptr<SyncCycleContext> cycle_context_;
  219. // TryJob might get called for multiple reasons. It should only call
  220. // DoPollSyncCycleJob after some time since the last attempt.
  221. // last_poll_reset_ keeps track of when was last attempt.
  222. base::TimeTicks last_poll_reset_;
  223. // next_sync_cycle_job_priority_ defines which priority will be used next
  224. // time TrySyncCycleJobImpl is called. CANARY_PRIORITY allows syncer to run
  225. // even if scheduler is in exponential backoff. This is needed for events that
  226. // have chance of resolving previous error (e.g. network connection change
  227. // after NETWORK_UNAVAILABLE error).
  228. // It is reset back to NORMAL_PRIORITY on every call to TrySyncCycleJobImpl.
  229. JobPriority next_sync_cycle_job_priority_;
  230. // One-shot timer for scheduling GU retry according to delay set by server.
  231. base::OneShotTimer retry_timer_;
  232. // Dictates if the scheduler should wait for authentication to happen or not.
  233. bool ignore_auth_credentials_;
  234. // Used to prevent changing nudge delays by the server in integration tests.
  235. bool force_short_nudge_delay_for_test_ = false;
  236. SEQUENCE_CHECKER(sequence_checker_);
  237. base::WeakPtrFactory<SyncSchedulerImpl> weak_ptr_factory_{this};
  238. };
  239. } // namespace syncer
  240. #endif // COMPONENTS_SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_