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

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

Issue 2130453004: [Sync] Move //sync to //components/sync. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 4 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
« no previous file with comments | « sync/engine/sync_scheduler.cc ('k') | sync/engine/sync_scheduler_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
5 #ifndef SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_
6 #define SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_
7
8 #include <map>
9 #include <memory>
10 #include <string>
11
12 #include "base/callback.h"
13 #include "base/cancelable_callback.h"
14 #include "base/compiler_specific.h"
15 #include "base/gtest_prod_util.h"
16 #include "base/macros.h"
17 #include "base/memory/linked_ptr.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/threading/non_thread_safe.h"
20 #include "base/time/time.h"
21 #include "base/timer/timer.h"
22 #include "sync/base/sync_export.h"
23 #include "sync/engine/net/server_connection_manager.h"
24 #include "sync/engine/nudge_source.h"
25 #include "sync/engine/sync_scheduler.h"
26 #include "sync/engine/syncer.h"
27 #include "sync/internal_api/public/engine/polling_constants.h"
28 #include "sync/internal_api/public/util/weak_handle.h"
29 #include "sync/sessions/nudge_tracker.h"
30 #include "sync/sessions/sync_session.h"
31 #include "sync/sessions/sync_session_context.h"
32
33 namespace syncer {
34
35 class BackoffDelayProvider;
36
37 namespace sessions {
38 struct ModelNeutralState;
39 }
40
41 class SYNC_EXPORT SyncSchedulerImpl : public SyncScheduler,
42 public base::NonThreadSafe {
43 public:
44 // |name| is a display string to identify the syncer thread. Takes
45 // |ownership of |syncer| and |delay_provider|.
46 SyncSchedulerImpl(const std::string& name,
47 BackoffDelayProvider* delay_provider,
48 sessions::SyncSessionContext* context,
49 Syncer* syncer);
50
51 // Calls Stop().
52 ~SyncSchedulerImpl() override;
53
54 void Start(Mode mode, base::Time last_poll_time) override;
55 void ScheduleConfiguration(const ConfigurationParams& params) override;
56 void ScheduleClearServerData(const ClearParams& params) override;
57 void Stop() override;
58 void ScheduleLocalNudge(
59 ModelTypeSet types,
60 const tracked_objects::Location& nudge_location) override;
61 void ScheduleLocalRefreshRequest(
62 ModelTypeSet types,
63 const tracked_objects::Location& nudge_location) override;
64 void ScheduleInvalidationNudge(
65 syncer::ModelType type,
66 std::unique_ptr<InvalidationInterface> invalidation,
67 const tracked_objects::Location& nudge_location) override;
68 void ScheduleInitialSyncNudge(syncer::ModelType model_type) override;
69 void SetNotificationsEnabled(bool notifications_enabled) override;
70
71 void OnCredentialsUpdated() override;
72 void OnConnectionStatusChange() override;
73
74 // SyncSession::Delegate implementation.
75 void OnThrottled(const base::TimeDelta& throttle_duration) override;
76 void OnTypesThrottled(ModelTypeSet types,
77 const base::TimeDelta& throttle_duration) override;
78 bool IsCurrentlyThrottled() override;
79 void OnReceivedShortPollIntervalUpdate(
80 const base::TimeDelta& new_interval) override;
81 void OnReceivedLongPollIntervalUpdate(
82 const base::TimeDelta& new_interval) override;
83 void OnReceivedCustomNudgeDelays(
84 const std::map<ModelType, base::TimeDelta>& nudge_delays) override;
85 void OnReceivedClientInvalidationHintBufferSize(int size) override;
86 void OnSyncProtocolError(
87 const SyncProtocolError& sync_protocol_error) override;
88 void OnReceivedGuRetryDelay(const base::TimeDelta& delay) override;
89 void OnReceivedMigrationRequest(syncer::ModelTypeSet types) override;
90
91 // Returns true if the client is currently in exponential backoff.
92 bool IsBackingOff() const;
93
94 private:
95 enum JobPriority {
96 // Non-canary jobs respect exponential backoff.
97 NORMAL_PRIORITY,
98 // Canary jobs bypass exponential backoff, so use with extreme caution.
99 CANARY_PRIORITY
100 };
101
102 enum PollAdjustType {
103 // Restart the poll interval.
104 FORCE_RESET,
105 // Restart the poll interval only if its length has changed.
106 UPDATE_INTERVAL,
107 };
108
109 friend class SyncSchedulerTest;
110 friend class SyncSchedulerWhiteboxTest;
111 friend class SyncerTest;
112
113 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest, TransientPollFailure);
114 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest,
115 ServerConnectionChangeDuringBackoff);
116 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest,
117 ConnectionChangeCanaryPreemptedByNudge);
118 FRIEND_TEST_ALL_PREFIXES(BackoffTriggersSyncSchedulerTest,
119 FailGetEncryptionKey);
120 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest, SuccessfulRetry);
121 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest, FailedRetry);
122 FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest, ReceiveNewRetryDelay);
123
124 struct SYNC_EXPORT WaitInterval {
125 enum Mode {
126 // Uninitialized state, should not be set in practice.
127 UNKNOWN = -1,
128 // We enter a series of increasingly longer WaitIntervals if we experience
129 // repeated transient failures. We retry at the end of each interval.
130 EXPONENTIAL_BACKOFF,
131 // A server-initiated throttled interval. We do not allow any syncing
132 // during such an interval.
133 THROTTLED,
134 };
135 WaitInterval();
136 ~WaitInterval();
137 WaitInterval(Mode mode, base::TimeDelta length);
138
139 static const char* GetModeString(Mode mode);
140
141 Mode mode;
142 base::TimeDelta length;
143 };
144
145 static const char* GetModeString(Mode mode);
146
147 void SetDefaultNudgeDelay(base::TimeDelta delay_ms);
148
149 // Invoke the syncer to perform a nudge job.
150 void DoNudgeSyncSessionJob(JobPriority priority);
151
152 // Invoke the syncer to perform a configuration job.
153 void DoConfigurationSyncSessionJob(JobPriority priority);
154
155 void DoClearServerDataSyncSessionJob(JobPriority priority);
156
157 // Helper function for Do{Nudge,Configuration,Poll}SyncSessionJob.
158 void HandleSuccess();
159
160 // Helper function for Do{Nudge,Configuration,Poll}SyncSessionJob.
161 void HandleFailure(
162 const sessions::ModelNeutralState& model_neutral_state);
163
164 // Invoke the Syncer to perform a poll job.
165 void DoPollSyncSessionJob();
166
167 // Helper function to calculate poll interval.
168 base::TimeDelta GetPollInterval();
169
170 // Adjusts the poll timer to account for new poll interval, and possibly
171 // resets the poll interval, depedning on the flag's value.
172 void AdjustPolling(PollAdjustType type);
173
174 // Helper to restart waiting with |wait_interval_|'s timer.
175 void RestartWaiting();
176
177 // Determines if we're allowed to contact the server right now.
178 bool CanRunJobNow(JobPriority priority);
179
180 // Determines if we're allowed to contact the server right now.
181 bool CanRunNudgeJobNow(JobPriority priority);
182
183 // If the scheduler's current state supports it, this will create a job based
184 // on the passed in parameters and coalesce it with any other pending jobs,
185 // then post a delayed task to run it. It may also choose to drop the job or
186 // save it for later, depending on the scheduler's current state.
187 void ScheduleNudgeImpl(
188 const base::TimeDelta& delay,
189 const tracked_objects::Location& nudge_location);
190
191 // Helper to signal listeners about changed retry time.
192 void NotifyRetryTime(base::Time retry_time);
193
194 // Helper to signal listeners about changed throttled types.
195 void NotifyThrottledTypesChanged(ModelTypeSet types);
196
197 // Looks for pending work and, if it finds any, run this work at "canary"
198 // priority.
199 void TryCanaryJob();
200
201 // At the moment TrySyncSessionJob just posts call to TrySyncSessionJobImpl on
202 // current thread. In the future it will request access token here.
203 void TrySyncSessionJob();
204 void TrySyncSessionJobImpl();
205
206 // Transitions out of the THROTTLED WaitInterval then calls TryCanaryJob().
207 void Unthrottle();
208
209 // Called when a per-type throttling interval expires.
210 void TypeUnthrottle(base::TimeTicks unthrottle_time);
211
212 // Runs a normal nudge job when the scheduled timer expires.
213 void PerformDelayedNudge();
214
215 // Attempts to exit EXPONENTIAL_BACKOFF by calling TryCanaryJob().
216 void ExponentialBackoffRetry();
217
218 // Called when the root cause of the current connection error is fixed.
219 void OnServerConnectionErrorFixed();
220
221 // Creates a session for a poll and performs the sync.
222 void PollTimerCallback();
223
224 // Creates a session for a retry and performs the sync.
225 void RetryTimerCallback();
226
227 // Returns the set of types that are enabled and not currently throttled.
228 ModelTypeSet GetEnabledAndUnthrottledTypes();
229
230 // Called as we are started to broadcast an initial session snapshot
231 // containing data like initial_sync_ended. Important when the client starts
232 // up and does not need to perform an initial sync.
233 void SendInitialSnapshot();
234
235 // This is used for histogramming and analysis of ScheduleNudge* APIs.
236 // SyncScheduler is the ultimate choke-point for all such invocations (with
237 // and without InvalidationState variants, all NudgeSources, etc) and as such
238 // is the most flexible place to do this bookkeeping.
239 void UpdateNudgeTimeRecords(ModelTypeSet types);
240
241 // For certain methods that need to worry about X-thread posting.
242 WeakHandle<SyncSchedulerImpl> weak_handle_this_;
243
244 // Used for logging.
245 const std::string name_;
246
247 // Set in Start(), unset in Stop().
248 bool started_;
249
250 // Modifiable versions of kDefaultLongPollIntervalSeconds which can be
251 // updated by the server.
252 base::TimeDelta syncer_short_poll_interval_seconds_;
253 base::TimeDelta syncer_long_poll_interval_seconds_;
254
255 // Timer for polling. Restarted on each successful poll, and when entering
256 // normal sync mode or exiting an error state. Not active in configuration
257 // mode.
258 base::OneShotTimer poll_timer_;
259
260 // The mode of operation.
261 Mode mode_;
262
263 // Current wait state. Null if we're not in backoff and not throttled.
264 std::unique_ptr<WaitInterval> wait_interval_;
265
266 std::unique_ptr<BackoffDelayProvider> delay_provider_;
267
268 // The event that will wake us up.
269 base::OneShotTimer pending_wakeup_timer_;
270
271 // An event that fires when data type throttling expires.
272 base::OneShotTimer type_unthrottle_timer_;
273
274 // Storage for variables related to an in-progress configure request. Note
275 // that (mode_ != CONFIGURATION_MODE) \implies !pending_configure_params_.
276 std::unique_ptr<ConfigurationParams> pending_configure_params_;
277
278 std::unique_ptr<ClearParams> pending_clear_params_;
279
280 // If we have a nudge pending to run soon, it will be listed here.
281 base::TimeTicks scheduled_nudge_time_;
282
283 // Keeps track of work that the syncer needs to handle.
284 sessions::NudgeTracker nudge_tracker_;
285
286 // Invoked to run through the sync cycle.
287 std::unique_ptr<Syncer> syncer_;
288
289 sessions::SyncSessionContext* session_context_;
290
291 // A map tracking LOCAL NudgeSource invocations of ScheduleNudge* APIs,
292 // organized by datatype. Each datatype that was part of the types requested
293 // in the call will have its TimeTicks value updated.
294 typedef std::map<ModelType, base::TimeTicks> ModelTypeTimeMap;
295 ModelTypeTimeMap last_local_nudges_by_model_type_;
296
297 // Used as an "anti-reentrancy defensive assertion".
298 // While true, it is illegal for any new scheduling activity to take place.
299 // Ensures that higher layers don't break this law in response to events that
300 // take place during a sync cycle. We call this out because such violations
301 // could result in tight sync loops hitting sync servers.
302 bool no_scheduling_allowed_;
303
304 // TryJob might get called for multiple reasons. It should only call
305 // DoPollSyncSessionJob after some time since the last attempt.
306 // last_poll_reset_ keeps track of when was last attempt.
307 base::TimeTicks last_poll_reset_;
308
309 // next_sync_session_job_priority_ defines which priority will be used next
310 // time TrySyncSessionJobImpl is called. CANARY_PRIORITY allows syncer to run
311 // even if scheduler is in exponential backoff. This is needed for events that
312 // have chance of resolving previous error (e.g. network connection change
313 // after NETWORK_UNAVAILABLE error).
314 // It is reset back to NORMAL_PRIORITY on every call to TrySyncSessionJobImpl.
315 JobPriority next_sync_session_job_priority_;
316
317 // One-shot timer for scheduling GU retry according to delay set by server.
318 base::OneShotTimer retry_timer_;
319
320 base::WeakPtrFactory<SyncSchedulerImpl> weak_ptr_factory_;
321
322 // A second factory specially for weak_handle_this_, to allow the handle
323 // to be const and alleviate threading concerns.
324 base::WeakPtrFactory<SyncSchedulerImpl> weak_ptr_factory_for_weak_handle_;
325
326 DISALLOW_COPY_AND_ASSIGN(SyncSchedulerImpl);
327 };
328
329 } // namespace syncer
330
331 #endif // SYNC_ENGINE_SYNC_SCHEDULER_IMPL_H_
OLDNEW
« no previous file with comments | « sync/engine/sync_scheduler.cc ('k') | sync/engine/sync_scheduler_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698