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

Side by Side Diff: chrome/browser/sync/engine/syncer_thread2.cc

Issue 6286067: sync: add a SyncSessionJobPurpose for clearing sync user data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/chrome
Patch Set: whitespace Created 9 years, 10 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 | Annotate | Revision Log
OLDNEW
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 #include "chrome/browser/sync/engine/syncer_thread2.h" 5 #include "chrome/browser/sync/engine/syncer_thread2.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/rand_util.h" 9 #include "base/rand_util.h"
10 #include "chrome/browser/sync/engine/syncer.h" 10 #include "chrome/browser/sync/engine/syncer.h"
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 mode_ = mode; 95 mode_ = mode;
96 AdjustPolling(NULL); // Will kick start poll timer if needed. 96 AdjustPolling(NULL); // Will kick start poll timer if needed.
97 } 97 }
98 98
99 bool SyncerThread::ShouldRunJob(SyncSessionJobPurpose purpose, 99 bool SyncerThread::ShouldRunJob(SyncSessionJobPurpose purpose,
100 const TimeTicks& scheduled_start) { 100 const TimeTicks& scheduled_start) {
101 DCHECK_EQ(MessageLoop::current(), thread_.message_loop()); 101 DCHECK_EQ(MessageLoop::current(), thread_.message_loop());
102 102
103 // Check wait interval. 103 // Check wait interval.
104 if (wait_interval_.get()) { 104 if (wait_interval_.get()) {
105 // TODO(tim): Consider different handling for CLEAR_USER_DATA (i.e. permit
106 // when throttled).
105 if (wait_interval_->mode == WaitInterval::THROTTLED) 107 if (wait_interval_->mode == WaitInterval::THROTTLED)
106 return false; 108 return false;
107 109
108 DCHECK_EQ(wait_interval_->mode, WaitInterval::EXPONENTIAL_BACKOFF); 110 DCHECK_EQ(wait_interval_->mode, WaitInterval::EXPONENTIAL_BACKOFF);
109 DCHECK(purpose == POLL || 111 DCHECK(purpose == POLL ||
110 purpose == NUDGE); 112 purpose == NUDGE);
111 if ((purpose != NUDGE) || wait_interval_->had_nudge) 113 if ((purpose != NUDGE) || wait_interval_->had_nudge)
112 return false; 114 return false;
113 } 115 }
114 116
115 // Mode / purpose contract (See 'Mode' enum in header). Don't run jobs that 117 // Mode / purpose contract (See 'Mode' enum in header). Don't run jobs that
116 // were intended for a normal sync if we are in configuration mode, and vice 118 // were intended for a normal sync if we are in configuration mode, and vice
117 // versa. 119 // versa.
118 switch (mode_) { 120 switch (mode_) {
Raz Mathias 2011/02/03 01:42:17 It seems like you are switching on Purpose a bunch
tim (not reviewing) 2011/02/03 18:18:52 I like this suggestion, except that right now the
Raz Mathias 2011/02/03 19:21:17 What I meant here was implementing a method on the
119 case CONFIGURATION_MODE: 121 case CONFIGURATION_MODE:
120 if (purpose != CONFIGURATION) 122 if (purpose != CONFIGURATION)
121 return false; 123 return false;
122 break; 124 break;
123 case NORMAL_MODE: 125 case NORMAL_MODE:
124 if (purpose != POLL && purpose != NUDGE) 126 if (purpose == CONFIGURATION)
125 return false; 127 return false;
126 break; 128 break;
127 default: 129 default:
128 NOTREACHED() << "Unknown SyncerThread Mode: " << mode_; 130 NOTREACHED() << "Unknown SyncerThread Mode: " << mode_;
129 return false; 131 return false;
130 } 132 }
131 133
132 // Continuation NUDGE tasks have priority over POLLs because they are the 134 // Continuation NUDGE tasks have priority over POLLs because they are the
133 // only tasks that trigger exponential backoff, so this prevents them from 135 // only tasks that trigger exponential backoff, so this prevents them from
134 // being starved from running (e.g. due to a very, very low poll interval, 136 // being starved from running (e.g. due to a very, very low poll interval,
(...skipping 16 matching lines...) Expand all
151 namespace { 153 namespace {
152 GetUpdatesCallerInfo::GetUpdatesSource GetUpdatesFromNudgeSource( 154 GetUpdatesCallerInfo::GetUpdatesSource GetUpdatesFromNudgeSource(
153 NudgeSource source) { 155 NudgeSource source) {
154 switch (source) { 156 switch (source) {
155 case NUDGE_SOURCE_NOTIFICATION: 157 case NUDGE_SOURCE_NOTIFICATION:
156 return GetUpdatesCallerInfo::NOTIFICATION; 158 return GetUpdatesCallerInfo::NOTIFICATION;
157 case NUDGE_SOURCE_LOCAL: 159 case NUDGE_SOURCE_LOCAL:
158 return GetUpdatesCallerInfo::LOCAL; 160 return GetUpdatesCallerInfo::LOCAL;
159 case NUDGE_SOURCE_CONTINUATION: 161 case NUDGE_SOURCE_CONTINUATION:
160 return GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION; 162 return GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION;
161 case NUDGE_SOURCE_CLEAR_PRIVATE_DATA:
162 return GetUpdatesCallerInfo::CLEAR_PRIVATE_DATA;
163 case NUDGE_SOURCE_UNKNOWN: 163 case NUDGE_SOURCE_UNKNOWN:
164 return GetUpdatesCallerInfo::UNKNOWN;
164 default: 165 default:
166 NOTREACHED();
165 return GetUpdatesCallerInfo::UNKNOWN; 167 return GetUpdatesCallerInfo::UNKNOWN;
166 } 168 }
167 } 169 }
168 170
169 // Functor for std::find_if to search by ModelSafeGroup. 171 // Functor for std::find_if to search by ModelSafeGroup.
170 struct WorkerGroupIs { 172 struct WorkerGroupIs {
171 explicit WorkerGroupIs(ModelSafeGroup group) : group(group) {} 173 explicit WorkerGroupIs(ModelSafeGroup group) : group(group) {}
172 bool operator()(ModelSafeWorker* w) { 174 bool operator()(ModelSafeWorker* w) {
173 return group == w->GetModelSafeGroup(); 175 return group == w->GetModelSafeGroup();
174 } 176 }
175 ModelSafeGroup group; 177 ModelSafeGroup group;
176 }; 178 };
177 } // namespace 179 } // namespace
178 180
181 void SyncerThread::ScheduleClearUserData() {
182 if (!thread_.IsRunning()) {
183 NOTREACHED();
184 return;
185 }
186 thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
187 this, &SyncerThread::ScheduleClearUserDataImpl));
188 }
189
179 void SyncerThread::ScheduleNudge(const TimeDelta& delay, 190 void SyncerThread::ScheduleNudge(const TimeDelta& delay,
180 NudgeSource source, const ModelTypeBitSet& types) { 191 NudgeSource source, const ModelTypeBitSet& types) {
181 if (!thread_.IsRunning()) { 192 if (!thread_.IsRunning()) {
182 NOTREACHED(); 193 NOTREACHED();
183 return; 194 return;
184 } 195 }
185 196
186 TypePayloadMap types_with_payloads = 197 TypePayloadMap types_with_payloads =
187 sessions::MakeTypePayloadMapFromBitSet(types, std::string()); 198 sessions::MakeTypePayloadMapFromBitSet(types, std::string());
188 thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod( 199 thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
189 this, &SyncerThread::ScheduleNudgeImpl, delay, source, 200 this, &SyncerThread::ScheduleNudgeImpl, delay, source,
190 types_with_payloads)); 201 types_with_payloads));
191 } 202 }
192 203
193 void SyncerThread::ScheduleNudgeWithPayloads(const TimeDelta& delay, 204 void SyncerThread::ScheduleNudgeWithPayloads(const TimeDelta& delay,
194 NudgeSource source, const TypePayloadMap& types_with_payloads) { 205 NudgeSource source, const TypePayloadMap& types_with_payloads) {
195 if (!thread_.IsRunning()) { 206 if (!thread_.IsRunning()) {
196 NOTREACHED(); 207 NOTREACHED();
197 return; 208 return;
198 } 209 }
199 210
200 thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod( 211 thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
201 this, &SyncerThread::ScheduleNudgeImpl, delay, source, 212 this, &SyncerThread::ScheduleNudgeImpl, delay, source,
202 types_with_payloads)); 213 types_with_payloads));
203 } 214 }
204 215
216 void SyncerThread::ScheduleClearUserDataImpl() {
217 DCHECK_EQ(MessageLoop::current(), thread_.message_loop());
218 SyncSession* session = new SyncSession(session_context_.get(), this,
219 SyncSourceInfo(), ModelSafeRoutingInfo(),
220 std::vector<ModelSafeWorker*>());
221 ScheduleSyncSessionJob(TimeDelta::FromSeconds(0), CLEAR_USER_DATA, session);
222 }
223
205 void SyncerThread::ScheduleNudgeImpl(const TimeDelta& delay, 224 void SyncerThread::ScheduleNudgeImpl(const TimeDelta& delay,
206 NudgeSource source, const TypePayloadMap& types_with_payloads) { 225 NudgeSource source, const TypePayloadMap& types_with_payloads) {
207 DCHECK_EQ(MessageLoop::current(), thread_.message_loop()); 226 DCHECK_EQ(MessageLoop::current(), thread_.message_loop());
208 TimeTicks rough_start = TimeTicks::Now() + delay; 227 TimeTicks rough_start = TimeTicks::Now() + delay;
209 if (!ShouldRunJob(NUDGE, rough_start))
210 return;
211 228
212 // Note we currently nudge for all types regardless of the ones incurring 229 // Note we currently nudge for all types regardless of the ones incurring
213 // the nudge. Doing different would throw off some syncer commands like 230 // the nudge. Doing different would throw off some syncer commands like
214 // CleanupDisabledTypes. We may want to change this in the future. 231 // CleanupDisabledTypes. We may want to change this in the future.
215 ModelSafeRoutingInfo routes; 232 ModelSafeRoutingInfo routes;
216 std::vector<ModelSafeWorker*> workers; 233 std::vector<ModelSafeWorker*> workers;
217 session_context_->registrar()->GetModelSafeRoutingInfo(&routes); 234 session_context_->registrar()->GetModelSafeRoutingInfo(&routes);
218 session_context_->registrar()->GetWorkers(&workers); 235 session_context_->registrar()->GetWorkers(&workers);
219 SyncSourceInfo info(GetUpdatesFromNudgeSource(source), 236 SyncSourceInfo info(GetUpdatesFromNudgeSource(source),
220 types_with_payloads); 237 types_with_payloads);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 SyncSessionJob job = {purpose, TimeTicks::Now() + delay, 318 SyncSessionJob job = {purpose, TimeTicks::Now() + delay,
302 make_linked_ptr(session)}; 319 make_linked_ptr(session)};
303 if (purpose == NUDGE) { 320 if (purpose == NUDGE) {
304 DCHECK(!pending_nudge_.get() || pending_nudge_->session.get() == session); 321 DCHECK(!pending_nudge_.get() || pending_nudge_->session.get() == session);
305 pending_nudge_.reset(new SyncSessionJob(job)); 322 pending_nudge_.reset(new SyncSessionJob(job));
306 } 323 }
307 MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(this, 324 MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(this,
308 &SyncerThread::DoSyncSessionJob, job), delay.InMilliseconds()); 325 &SyncerThread::DoSyncSessionJob, job), delay.InMilliseconds());
309 } 326 }
310 327
328 void SyncerThread::SetSyncerStepsForPurpose(SyncSessionJobPurpose purpose,
Raz Mathias 2011/02/03 01:42:17 It seems a little strange that the syncer, which s
tim (not reviewing) 2011/02/03 18:18:52 Did you mean SyncerThread vs Syncer? Because this
Raz Mathias 2011/02/03 19:21:17 Yes, sorry, SyncerThread -- This switch block with
329 SyncerStep* start, SyncerStep* end) {
330 *end = SYNCER_END;
331 switch (purpose) {
332 case CONFIGURATION:
333 *start = DOWNLOAD_UPDATES;
334 *end = APPLY_UPDATES;
335 return;
336 case CLEAR_USER_DATA:
337 *start = CLEAR_PRIVATE_DATA;
338 return;
339 case NUDGE:
340 case POLL:
341 *start = SYNCER_BEGIN;
342 return;
343 default:
344 NOTREACHED();
345 }
346 }
347
311 void SyncerThread::DoSyncSessionJob(const SyncSessionJob& job) { 348 void SyncerThread::DoSyncSessionJob(const SyncSessionJob& job) {
312 DCHECK_EQ(MessageLoop::current(), thread_.message_loop()); 349 DCHECK_EQ(MessageLoop::current(), thread_.message_loop());
313 350
314 if (job.purpose == NUDGE) { 351 if (job.purpose == NUDGE) {
315 DCHECK(pending_nudge_.get()); 352 DCHECK(pending_nudge_.get());
316 if (pending_nudge_->session != job.session) 353 if (pending_nudge_->session != job.session)
317 return; // Another nudge must have been scheduled in in the meantime. 354 return; // Another nudge must have been scheduled in in the meantime.
318 pending_nudge_.reset(); 355 pending_nudge_.reset();
319 } else if (job.purpose == CONFIGURATION) {
320 NOTIMPLEMENTED() << "TODO(tim): SyncShare [DOWNLOAD_UPDATES,APPLY_UPDATES]";
321 } 356 }
322 357
358 SyncerStep begin(SYNCER_BEGIN);
359 SyncerStep end(SYNCER_END);
360 SetSyncerStepsForPurpose(job.purpose, &begin, &end);
361
323 bool has_more_to_sync = true; 362 bool has_more_to_sync = true;
324 bool did_job = false; 363 bool did_job = false;
325 while (ShouldRunJob(job.purpose, job.scheduled_start) && has_more_to_sync) { 364 while (ShouldRunJob(job.purpose, job.scheduled_start) && has_more_to_sync) {
326 VLOG(1) << "SyncerThread: Calling SyncShare."; 365 VLOG(1) << "SyncerThread: Calling SyncShare.";
327 did_job = true; 366 did_job = true;
328 // Synchronously perform the sync session from this thread. 367 // Synchronously perform the sync session from this thread.
329 syncer_->SyncShare(job.session.get()); 368 syncer_->SyncShare(job.session.get(), begin, end);
330 has_more_to_sync = job.session->HasMoreToSync(); 369 has_more_to_sync = job.session->HasMoreToSync();
331 if (has_more_to_sync) 370 if (has_more_to_sync)
332 job.session->ResetTransientState(); 371 job.session->ResetTransientState();
333 } 372 }
334 VLOG(1) << "SyncerThread: Done SyncShare looping."; 373 VLOG(1) << "SyncerThread: Done SyncShare looping.";
335 if (did_job) 374 if (did_job)
336 FinishSyncSessionJob(job); 375 FinishSyncSessionJob(job);
337 } 376 }
338 377
339 void SyncerThread::FinishSyncSessionJob(const SyncSessionJob& job) { 378 void SyncerThread::FinishSyncSessionJob(const SyncSessionJob& job) {
(...skipping 28 matching lines...) Expand all
368 // 500, is likely to have occurred during commit). 407 // 500, is likely to have occurred during commit).
369 const bool work_to_do = 408 const bool work_to_do =
370 old_job.session->status_controller()->num_server_changes_remaining() > 0 409 old_job.session->status_controller()->num_server_changes_remaining() > 0
371 || old_job.session->status_controller()->unsynced_handles().size() > 0; 410 || old_job.session->status_controller()->unsynced_handles().size() > 0;
372 VLOG(1) << "syncer has work to do: " << work_to_do; 411 VLOG(1) << "syncer has work to do: " << work_to_do;
373 412
374 AdjustPolling(&old_job); 413 AdjustPolling(&old_job);
375 414
376 // TODO(tim): Old impl had special code if notifications disabled. Needed? 415 // TODO(tim): Old impl had special code if notifications disabled. Needed?
377 if (!work_to_do) { 416 if (!work_to_do) {
378 wait_interval_.reset(); // Success implies backoff relief. 417 // Success implies backoff relief. Note that if this was a "one-off" job
418 // (i.e. purpose == CLEAR_USER_DATA), if there was work_to_do before it
419 // ran this wont have changed, as jobs like this don't run a full sync
420 // cycle. So we don't need special code here.
421 wait_interval_.reset();
379 return; 422 return;
380 } 423 }
381 424
382 if (old_job.session->source().updates_source == 425 if (old_job.session->source().updates_source ==
383 GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION) { 426 GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION) {
384 // We don't seem to have made forward progress. Start or extend backoff. 427 // We don't seem to have made forward progress. Start or extend backoff.
385 HandleConsecutiveContinuationError(old_job); 428 HandleConsecutiveContinuationError(old_job);
386 } else if (IsBackingOff()) { 429 } else if (IsBackingOff()) {
387 // We weren't continuing but we're in backoff; must have been a nudge. 430 // We weren't continuing but we're in backoff; must have been a nudge.
388 DCHECK_EQ(NUDGE, old_job.purpose); 431 DCHECK_EQ(NUDGE, old_job.purpose);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 const ServerConnectionEvent& event) { 578 const ServerConnectionEvent& event) {
536 NOTIMPLEMENTED(); 579 NOTIMPLEMENTED();
537 } 580 }
538 581
539 void SyncerThread::set_notifications_enabled(bool notifications_enabled) { 582 void SyncerThread::set_notifications_enabled(bool notifications_enabled) {
540 session_context_->set_notifications_enabled(notifications_enabled); 583 session_context_->set_notifications_enabled(notifications_enabled);
541 } 584 }
542 585
543 } // s3 586 } // s3
544 } // browser_sync 587 } // browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/syncer_thread2.h ('k') | chrome/browser/sync/engine/syncer_thread2_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698