Chromium Code Reviews

Side by Side Diff: chrome/browser/sync/engine/syncer_thread.h

Issue 275015: For sync exponential backoff, allow one nudge per exponential backoff interva... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/sync/engine/syncer_thread.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 // This is the default implementation of SyncerThread whose Stop implementation 6 // This is the default implementation of SyncerThread whose Stop implementation
7 // does not support a timeout, but is greatly simplified. 7 // does not support a timeout, but is greatly simplified.
8 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ 8 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_
9 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ 9 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_
10 10
(...skipping 56 matching lines...)
67 }; 67 };
68 68
69 class SyncerThread : public base::RefCountedThreadSafe<SyncerThread> { 69 class SyncerThread : public base::RefCountedThreadSafe<SyncerThread> {
70 FRIEND_TEST(SyncerThreadTest, CalculateSyncWaitTime); 70 FRIEND_TEST(SyncerThreadTest, CalculateSyncWaitTime);
71 FRIEND_TEST(SyncerThreadTest, CalculatePollingWaitTime); 71 FRIEND_TEST(SyncerThreadTest, CalculatePollingWaitTime);
72 FRIEND_TEST(SyncerThreadWithSyncerTest, Polling); 72 FRIEND_TEST(SyncerThreadWithSyncerTest, Polling);
73 FRIEND_TEST(SyncerThreadWithSyncerTest, Nudge); 73 FRIEND_TEST(SyncerThreadWithSyncerTest, Nudge);
74 friend class SyncerThreadWithSyncerTest; 74 friend class SyncerThreadWithSyncerTest;
75 friend class SyncerThreadFactory; 75 friend class SyncerThreadFactory;
76 public: 76 public:
77 // Encapsulates the parameters that make up an interval on which the
78 // syncer thread is sleeping.
79 struct WaitInterval {
80 enum Mode {
81 // A wait interval whose duration has not been affected by exponential
82 // backoff. The base case for exponential backoff falls in to this case
83 // (e.g when the exponent is 1). So far, we don't need a separate case.
84 // NORMAL intervals are not nudge-rate limited.
85 NORMAL,
86 // A wait interval whose duration has been affected by exponential
87 // backoff.
88 // EXPONENTIAL_BACKOFF intervals are nudge-rate limited to 1 per interval.
89 EXPONENTIAL_BACKOFF,
90 };
91
92 Mode mode;
93 // This bool is set to true if we have observed a nudge during during this
94 // interval and mode == EXPONENTIAL_BACKOFF.
95 bool had_nudge_during_backoff;
96 base::TimeDelta poll_delta; // The wait duration until the next poll.
97
98 WaitInterval() : mode(NORMAL), had_nudge_during_backoff(false) { }
99 };
100
77 enum NudgeSource { 101 enum NudgeSource {
78 kUnknown = 0, 102 kUnknown = 0,
79 kNotification, 103 kNotification,
80 kLocal, 104 kLocal,
81 kContinuation 105 kContinuation
82 }; 106 };
83 // Server can overwrite these values via client commands. 107 // Server can overwrite these values via client commands.
84 // Standard short poll. This is used when XMPP is off. 108 // Standard short poll. This is used when XMPP is off.
85 static const int kDefaultShortPollIntervalSeconds = 60; 109 static const int kDefaultShortPollIntervalSeconds = 60;
86 // Long poll is used when XMPP is on. 110 // Long poll is used when XMPP is on.
87 static const int kDefaultLongPollIntervalSeconds = 3600; 111 static const int kDefaultLongPollIntervalSeconds = 3600;
88 // 30 minutes by default. If exponential backoff kicks in, this is the 112 // 30 minutes by default. If exponential backoff kicks in, this is the
89 // longest possible poll interval. 113 // longest possible poll interval.
90 static const int kDefaultMaxPollIntervalMs = 30 * 60 * 1000; 114 static const int kDefaultMaxPollIntervalMs = 30 * 60 * 1000;
91 115
92 virtual ~SyncerThread(); 116 virtual ~SyncerThread();
93 117
94 virtual void WatchConnectionManager(ServerConnectionManager* conn_mgr); 118 virtual void WatchConnectionManager(ServerConnectionManager* conn_mgr);
95 119
96 // Starts a syncer thread. 120 // Starts a syncer thread.
97 // Returns true if it creates a thread or if there's currently a thread 121 // Returns true if it creates a thread or if there's currently a thread
98 // running and false otherwise. 122 // running and false otherwise.
99 virtual bool Start(); 123 virtual bool Start();
100 124
101 // Stop processing. |max_wait| doesn't do anything in this version. 125 // Stop processing. |max_wait| doesn't do anything in this version.
102 virtual bool Stop(int max_wait); 126 virtual bool Stop(int max_wait);
103 127
104 // Nudges the syncer to sync with a delay specified. This API is for access 128 // Nudges the syncer to sync with a delay specified. This API is for access
105 // from the SyncerThread's controller and will cause a mutex lock. 129 // from the SyncerThread's controller and will cause a mutex lock.
106 virtual bool NudgeSyncer(int milliseconds_from_now, NudgeSource source); 130 virtual void NudgeSyncer(int milliseconds_from_now, NudgeSource source);
107 131
108 // Registers this thread to watch talk mediator events. 132 // Registers this thread to watch talk mediator events.
109 virtual void WatchTalkMediator(TalkMediator* talk_mediator); 133 virtual void WatchTalkMediator(TalkMediator* talk_mediator);
110 134
111 virtual void WatchClientCommands(ClientCommandChannel* channel); 135 virtual void WatchClientCommands(ClientCommandChannel* channel);
112 136
113 virtual SyncerEventChannel* channel(); 137 virtual SyncerEventChannel* channel();
114 138
115 protected: 139 protected:
116 SyncerThread(); // Necessary for temporary pthreads-based PIMPL impl. 140 SyncerThread(); // Necessary for temporary pthreads-based PIMPL impl.
(...skipping 48 matching lines...)
165 189
166 Syncer* syncer_; 190 Syncer* syncer_;
167 191
168 // State of the server connection. 192 // State of the server connection.
169 bool connected_; 193 bool connected_;
170 194
171 // A queue of all scheduled nudges. One insertion for every call to 195 // A queue of all scheduled nudges. One insertion for every call to
172 // NudgeQueue(). 196 // NudgeQueue().
173 NudgeQueue nudge_queue_; 197 NudgeQueue nudge_queue_;
174 198
199 // The wait interval for to the current iteration of our main loop. This is
200 // only written to by the syncer thread, and since the only reader from a
201 // different thread (NudgeSync) is called at totally random times, we don't
202 // really need to access mutually exclusively as the data races that exist
203 // are intrinsic, but do so anyway and avoid using 'volatile'.
204 WaitInterval current_wait_interval_;
205
175 ProtectedFields() 206 ProtectedFields()
176 : stop_syncer_thread_(false), syncer_(NULL), connected_(false) {} 207 : stop_syncer_thread_(false), syncer_(NULL), connected_(false) {}
177 } vault_; 208 } vault_;
178 209
179 // Gets signaled whenever a thread outside of the syncer thread changes a 210 // Gets signaled whenever a thread outside of the syncer thread changes a
180 // protected field in the vault_. 211 // protected field in the vault_.
181 ConditionVariable vault_field_changed_; 212 ConditionVariable vault_field_changed_;
182 213
183 // Used to lock everything in |vault_|. 214 // Used to lock everything in |vault_|.
184 Lock lock_; 215 Lock lock_;
185 216
186 private: 217 private:
187 // A few members to gate the rate at which we nudge the syncer.
188 enum {
189 kNudgeRateLimitCount = 6,
190 kNudgeRateLimitTime = 180,
191 };
192
193 // Threshold multipler for how long before user should be considered idle. 218 // Threshold multipler for how long before user should be considered idle.
194 static const int kPollBackoffThresholdMultiplier = 10; 219 static const int kPollBackoffThresholdMultiplier = 10;
195 220
196 friend void* RunSyncerThread(void* syncer_thread); 221 friend void* RunSyncerThread(void* syncer_thread);
197 void* Run(); 222 void* Run();
198 void HandleDirectoryManagerEvent( 223 void HandleDirectoryManagerEvent(
199 const syncable::DirectoryManagerEvent& event); 224 const syncable::DirectoryManagerEvent& event);
200 void HandleSyncerEvent(const SyncerEvent& event); 225 void HandleSyncerEvent(const SyncerEvent& event);
201 void HandleClientCommand(ClientCommandChannel::EventType event); 226 void HandleClientCommand(ClientCommandChannel::EventType event);
202 227
203 void HandleServerConnectionEvent(const ServerConnectionEvent& event); 228 void HandleServerConnectionEvent(const ServerConnectionEvent& event);
204 229
205 void HandleTalkMediatorEvent(const TalkMediatorEvent& event); 230 void HandleTalkMediatorEvent(const TalkMediatorEvent& event);
206 231
207 void SyncMain(Syncer* syncer); 232 void SyncMain(Syncer* syncer);
208 233
209 // Calculates the next sync wait time in seconds. last_poll_wait is the time 234 // Calculates the next sync wait time and exponential backoff state.
210 // duration of the previous polling timeout which was used. 235 // last_poll_wait is the time duration of the previous polling timeout which
211 // user_idle_milliseconds is updated by this method, and is a report of the 236 // was used. user_idle_milliseconds is updated by this method, and is a report
212 // full amount of time since the last period of activity for the user. The 237 // of the full amount of time since the last period of activity for the user.
213 // continue_sync_cycle parameter is used to determine whether or not we are 238 // The continue_sync_cycle parameter is used to determine whether or not we
214 // calculating a polling wait time that is a continuation of an sync cycle 239 // are calculating a polling wait time that is a continuation of an sync cycle
215 // which terminated while the syncer still had work to do. 240 // which terminated while the syncer still had work to do. was_nudged is used
216 virtual int CalculatePollingWaitTime( 241 // in case of exponential backoff so we only allow one nudge per backoff
242 // interval.
243 WaitInterval CalculatePollingWaitTime(
217 const AllStatus::Status& status, 244 const AllStatus::Status& status,
218 int last_poll_wait, // in s 245 int last_poll_wait, // in s
219 int* user_idle_milliseconds, 246 int* user_idle_milliseconds,
220 bool* continue_sync_cycle); 247 bool* continue_sync_cycle,
248 bool was_nudged);
249
221 // Helper to above function, considers effect of user idle time. 250 // Helper to above function, considers effect of user idle time.
222 virtual int CalculateSyncWaitTime(int last_wait, int user_idle_ms); 251 virtual int CalculateSyncWaitTime(int last_wait, int user_idle_ms);
223 252
224 // Sets the source value of the controlled syncer's updates_source value. 253 // Sets the source value of the controlled syncer's updates_source value.
225 // The initial sync boolean is updated if read as a sentinel. The following 254 // The initial sync boolean is updated if read as a sentinel. The following
226 // two methods work in concert to achieve this goal. 255 // two methods work in concert to achieve this goal. Returns true if it
227 void UpdateNudgeSource(bool* continue_sync_cycle, 256 // determines a nudge actually occurred.
257 bool UpdateNudgeSource(bool continue_sync_cycle,
228 bool* initial_sync); 258 bool* initial_sync);
229 void SetUpdatesSource(bool nudged, NudgeSource nudge_source, 259 void SetUpdatesSource(bool nudged, NudgeSource nudge_source,
230 bool* initial_sync); 260 bool* initial_sync);
231 261
232 // For unit tests only. 262 // For unit tests only.
233 virtual void DisableIdleDetection() { disable_idle_detection_ = true; } 263 virtual void DisableIdleDetection() { disable_idle_detection_ = true; }
234 264
235 // State of the notification framework is tracked by these values. 265 // State of the notification framework is tracked by these values.
236 bool p2p_authenticated_; 266 bool p2p_authenticated_;
237 bool p2p_subscribed_; 267 bool p2p_subscribed_;
(...skipping 38 matching lines...)
276 306
277 // Useful for unit tests 307 // Useful for unit tests
278 bool disable_idle_detection_; 308 bool disable_idle_detection_;
279 309
280 DISALLOW_COPY_AND_ASSIGN(SyncerThread); 310 DISALLOW_COPY_AND_ASSIGN(SyncerThread);
281 }; 311 };
282 312
283 } // namespace browser_sync 313 } // namespace browser_sync
284 314
285 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ 315 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/sync/engine/syncer_thread.cc » ('j') | no next file with comments »

Powered by Google App Engine