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

Side by Side Diff: components/sync/engine_impl/sync_scheduler_impl.cc

Issue 2475043002: [Sync] Sync client should to exponential backoff when receive partial failure (Closed)
Patch Set: rebase Created 4 years, 1 month 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "components/sync/engine_impl/sync_scheduler_impl.h" 5 #include "components/sync/engine_impl/sync_scheduler_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstring> 8 #include <cstring>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 } 81 }
82 82
83 void RunAndReset(base::Closure* task) { 83 void RunAndReset(base::Closure* task) {
84 DCHECK(task); 84 DCHECK(task);
85 if (task->is_null()) 85 if (task->is_null())
86 return; 86 return;
87 task->Run(); 87 task->Run();
88 task->Reset(); 88 task->Reset();
89 } 89 }
90 90
91 #define ENUM_CASE(x) \
92 case x: \
93 return #x; \
94 break;
95
91 } // namespace 96 } // namespace
92 97
93 ConfigurationParams::ConfigurationParams() 98 ConfigurationParams::ConfigurationParams()
94 : source(GetUpdatesCallerInfo::UNKNOWN) {} 99 : source(GetUpdatesCallerInfo::UNKNOWN) {}
95 ConfigurationParams::ConfigurationParams( 100 ConfigurationParams::ConfigurationParams(
96 const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, 101 const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source,
97 ModelTypeSet types_to_download, 102 ModelTypeSet types_to_download,
98 const ModelSafeRoutingInfo& routing_info, 103 const ModelSafeRoutingInfo& routing_info,
99 const base::Closure& ready_task, 104 const base::Closure& ready_task,
100 const base::Closure& retry_task) 105 const base::Closure& retry_task)
101 : source(source), 106 : source(source),
102 types_to_download(types_to_download), 107 types_to_download(types_to_download),
103 routing_info(routing_info), 108 routing_info(routing_info),
104 ready_task(ready_task), 109 ready_task(ready_task),
105 retry_task(retry_task) { 110 retry_task(retry_task) {
106 DCHECK(!ready_task.is_null()); 111 DCHECK(!ready_task.is_null());
107 } 112 }
108 ConfigurationParams::ConfigurationParams(const ConfigurationParams& other) = 113 ConfigurationParams::ConfigurationParams(const ConfigurationParams& other) =
109 default; 114 default;
110 ConfigurationParams::~ConfigurationParams() {} 115 ConfigurationParams::~ConfigurationParams() {}
111 116
112 ClearParams::ClearParams(const base::Closure& report_success_task) 117 ClearParams::ClearParams(const base::Closure& report_success_task)
113 : report_success_task(report_success_task) { 118 : report_success_task(report_success_task) {
114 DCHECK(!report_success_task.is_null()); 119 DCHECK(!report_success_task.is_null());
115 } 120 }
116 ClearParams::ClearParams(const ClearParams& other) = default; 121 ClearParams::ClearParams(const ClearParams& other) = default;
117 ClearParams::~ClearParams() {} 122 ClearParams::~ClearParams() {}
118 123
119 SyncSchedulerImpl::WaitInterval::WaitInterval() : mode(UNKNOWN) {}
120
121 SyncSchedulerImpl::WaitInterval::WaitInterval(Mode mode, TimeDelta length)
122 : mode(mode), length(length) {}
123
124 SyncSchedulerImpl::WaitInterval::~WaitInterval() {}
125
126 #define ENUM_CASE(x) \
127 case x: \
128 return #x; \
129 break;
130
131 const char* SyncSchedulerImpl::WaitInterval::GetModeString(Mode mode) {
132 switch (mode) {
133 ENUM_CASE(UNKNOWN);
134 ENUM_CASE(EXPONENTIAL_BACKOFF);
135 ENUM_CASE(THROTTLED);
136 }
137 NOTREACHED();
138 return "";
139 }
140
141 GetUpdatesCallerInfo::GetUpdatesSource GetUpdatesFromNudgeSource( 124 GetUpdatesCallerInfo::GetUpdatesSource GetUpdatesFromNudgeSource(
142 NudgeSource source) { 125 NudgeSource source) {
143 switch (source) { 126 switch (source) {
144 case NUDGE_SOURCE_NOTIFICATION: 127 case NUDGE_SOURCE_NOTIFICATION:
145 return GetUpdatesCallerInfo::NOTIFICATION; 128 return GetUpdatesCallerInfo::NOTIFICATION;
146 case NUDGE_SOURCE_LOCAL: 129 case NUDGE_SOURCE_LOCAL:
147 return GetUpdatesCallerInfo::LOCAL; 130 return GetUpdatesCallerInfo::LOCAL;
148 case NUDGE_SOURCE_LOCAL_REFRESH: 131 case NUDGE_SOURCE_LOCAL_REFRESH:
149 return GetUpdatesCallerInfo::DATATYPE_REFRESH; 132 return GetUpdatesCallerInfo::DATATYPE_REFRESH;
150 case NUDGE_SOURCE_UNKNOWN: 133 case NUDGE_SOURCE_UNKNOWN:
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 Mode old_mode = mode_; 227 Mode old_mode = mode_;
245 mode_ = mode; 228 mode_ = mode;
246 // Only adjust the poll reset time if it was valid and in the past. 229 // Only adjust the poll reset time if it was valid and in the past.
247 if (!last_poll_time.is_null() && last_poll_time < base::Time::Now()) { 230 if (!last_poll_time.is_null() && last_poll_time < base::Time::Now()) {
248 // Convert from base::Time to base::TimeTicks. The reason we use Time 231 // Convert from base::Time to base::TimeTicks. The reason we use Time
249 // for persisting is that TimeTicks can stop making forward progress when 232 // for persisting is that TimeTicks can stop making forward progress when
250 // the machine is suspended. This implies that on resume the client might 233 // the machine is suspended. This implies that on resume the client might
251 // actually have miss the real poll, unless the client is restarted. Fixing 234 // actually have miss the real poll, unless the client is restarted. Fixing
252 // that would require using an AlarmTimer though, which is only supported 235 // that would require using an AlarmTimer though, which is only supported
253 // on certain platforms. 236 // on certain platforms.
254 last_poll_reset_ = 237 last_poll_reset_ = TimeTicks::Now() - (base::Time::Now() - last_poll_time);
255 base::TimeTicks::Now() - (base::Time::Now() - last_poll_time);
256 } 238 }
257 239
258 if (old_mode != mode_ && mode_ == NORMAL_MODE) { 240 if (old_mode != mode_ && mode_ == NORMAL_MODE) {
259 // We just got back to normal mode. Let's try to run the work that was 241 // We just got back to normal mode. Let's try to run the work that was
260 // queued up while we were configuring. 242 // queued up while we were configuring.
261 243
262 AdjustPolling(UPDATE_INTERVAL); // Will kick start poll timer if needed. 244 AdjustPolling(UPDATE_INTERVAL); // Will kick start poll timer if needed.
263 245
264 // Update our current time before checking IsRetryRequired(). 246 // Update our current time before checking IsRetryRequired().
265 nudge_tracker_.SetSyncCycleStartTime(base::TimeTicks::Now()); 247 nudge_tracker_.SetSyncCycleStartTime(TimeTicks::Now());
266 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) { 248 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) {
267 TrySyncCycleJob(); 249 TrySyncCycleJob();
268 } 250 }
269 } 251 }
270 } 252 }
271 253
272 ModelTypeSet SyncSchedulerImpl::GetEnabledAndUnthrottledTypes() { 254 ModelTypeSet SyncSchedulerImpl::GetEnabledAndUnblockedTypes() {
273 ModelTypeSet enabled_types = cycle_context_->GetEnabledTypes(); 255 ModelTypeSet enabled_types = cycle_context_->GetEnabledTypes();
274 ModelTypeSet enabled_protocol_types = 256 ModelTypeSet enabled_protocol_types =
275 Intersection(ProtocolTypes(), enabled_types); 257 Intersection(ProtocolTypes(), enabled_types);
276 ModelTypeSet throttled_types = nudge_tracker_.GetThrottledTypes(); 258 ModelTypeSet blocked_types = nudge_tracker_.GetBlockedTypes();
277 return Difference(enabled_protocol_types, throttled_types); 259 return Difference(enabled_protocol_types, blocked_types);
278 } 260 }
279 261
280 void SyncSchedulerImpl::SendInitialSnapshot() { 262 void SyncSchedulerImpl::SendInitialSnapshot() {
281 DCHECK(CalledOnValidThread()); 263 DCHECK(CalledOnValidThread());
282 std::unique_ptr<SyncCycle> dummy(SyncCycle::Build(cycle_context_, this)); 264 std::unique_ptr<SyncCycle> dummy(SyncCycle::Build(cycle_context_, this));
283 SyncCycleEvent event(SyncCycleEvent::STATUS_CHANGED); 265 SyncCycleEvent event(SyncCycleEvent::STATUS_CHANGED);
284 event.snapshot = dummy->TakeSnapshot(); 266 event.snapshot = dummy->TakeSnapshot();
285 for (auto& observer : *cycle_context_->listeners()) 267 for (auto& observer : *cycle_context_->listeners())
286 observer.OnSyncCycleEvent(event); 268 observer.OnSyncCycleEvent(event);
287 } 269 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 347
366 bool SyncSchedulerImpl::CanRunNudgeJobNow(JobPriority priority) { 348 bool SyncSchedulerImpl::CanRunNudgeJobNow(JobPriority priority) {
367 DCHECK(CalledOnValidThread()); 349 DCHECK(CalledOnValidThread());
368 350
369 if (!CanRunJobNow(priority)) { 351 if (!CanRunJobNow(priority)) {
370 SDVLOG(1) << "Unable to run a nudge job right now"; 352 SDVLOG(1) << "Unable to run a nudge job right now";
371 return false; 353 return false;
372 } 354 }
373 355
374 const ModelTypeSet enabled_types = cycle_context_->GetEnabledTypes(); 356 const ModelTypeSet enabled_types = cycle_context_->GetEnabledTypes();
375 if (nudge_tracker_.GetThrottledTypes().HasAll(enabled_types)) { 357 if (nudge_tracker_.GetBlockedTypes().HasAll(enabled_types)) {
376 SDVLOG(1) << "Not running a nudge because we're fully type throttled."; 358 SDVLOG(1) << "Not running a nudge because we're fully type throttled or "
359 "backed off.";
377 return false; 360 return false;
378 } 361 }
379 362
380 if (mode_ != NORMAL_MODE) { 363 if (mode_ != NORMAL_MODE) {
381 SDVLOG(1) << "Not running nudge because we're not in normal mode."; 364 SDVLOG(1) << "Not running nudge because we're not in normal mode.";
382 return false; 365 return false;
383 } 366 }
384 367
385 return true; 368 return true;
386 } 369 }
387 370
388 void SyncSchedulerImpl::ScheduleLocalNudge( 371 void SyncSchedulerImpl::ScheduleLocalNudge(
389 ModelTypeSet types, 372 ModelTypeSet types,
390 const tracked_objects::Location& nudge_location) { 373 const tracked_objects::Location& nudge_location) {
391 DCHECK(CalledOnValidThread()); 374 DCHECK(CalledOnValidThread());
392 DCHECK(!types.Empty()); 375 DCHECK(!types.Empty());
393 376
394 SDVLOG_LOC(nudge_location, 2) << "Scheduling sync because of local change to " 377 SDVLOG_LOC(nudge_location, 2) << "Scheduling sync because of local change to "
395 << ModelTypeSetToString(types); 378 << ModelTypeSetToString(types);
396 UpdateNudgeTimeRecords(types); 379 UpdateNudgeTimeRecords(types);
397 base::TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(types); 380 TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(types);
398 ScheduleNudgeImpl(nudge_delay, nudge_location); 381 ScheduleNudgeImpl(nudge_delay, nudge_location);
399 } 382 }
400 383
401 void SyncSchedulerImpl::ScheduleLocalRefreshRequest( 384 void SyncSchedulerImpl::ScheduleLocalRefreshRequest(
402 ModelTypeSet types, 385 ModelTypeSet types,
403 const tracked_objects::Location& nudge_location) { 386 const tracked_objects::Location& nudge_location) {
404 DCHECK(CalledOnValidThread()); 387 DCHECK(CalledOnValidThread());
405 DCHECK(!types.Empty()); 388 DCHECK(!types.Empty());
406 389
407 SDVLOG_LOC(nudge_location, 2) 390 SDVLOG_LOC(nudge_location, 2)
408 << "Scheduling sync because of local refresh request for " 391 << "Scheduling sync because of local refresh request for "
409 << ModelTypeSetToString(types); 392 << ModelTypeSetToString(types);
410 base::TimeDelta nudge_delay = nudge_tracker_.RecordLocalRefreshRequest(types); 393 TimeDelta nudge_delay = nudge_tracker_.RecordLocalRefreshRequest(types);
411 ScheduleNudgeImpl(nudge_delay, nudge_location); 394 ScheduleNudgeImpl(nudge_delay, nudge_location);
412 } 395 }
413 396
414 void SyncSchedulerImpl::ScheduleInvalidationNudge( 397 void SyncSchedulerImpl::ScheduleInvalidationNudge(
415 ModelType model_type, 398 ModelType model_type,
416 std::unique_ptr<InvalidationInterface> invalidation, 399 std::unique_ptr<InvalidationInterface> invalidation,
417 const tracked_objects::Location& nudge_location) { 400 const tracked_objects::Location& nudge_location) {
418 DCHECK(CalledOnValidThread()); 401 DCHECK(CalledOnValidThread());
419 402
420 SDVLOG_LOC(nudge_location, 2) 403 SDVLOG_LOC(nudge_location, 2)
421 << "Scheduling sync because we received invalidation for " 404 << "Scheduling sync because we received invalidation for "
422 << ModelTypeToString(model_type); 405 << ModelTypeToString(model_type);
423 base::TimeDelta nudge_delay = nudge_tracker_.RecordRemoteInvalidation( 406 TimeDelta nudge_delay = nudge_tracker_.RecordRemoteInvalidation(
424 model_type, std::move(invalidation)); 407 model_type, std::move(invalidation));
425 ScheduleNudgeImpl(nudge_delay, nudge_location); 408 ScheduleNudgeImpl(nudge_delay, nudge_location);
426 } 409 }
427 410
428 void SyncSchedulerImpl::ScheduleInitialSyncNudge(ModelType model_type) { 411 void SyncSchedulerImpl::ScheduleInitialSyncNudge(ModelType model_type) {
429 DCHECK(CalledOnValidThread()); 412 DCHECK(CalledOnValidThread());
430 413
431 SDVLOG(2) << "Scheduling non-blocking initial sync for " 414 SDVLOG(2) << "Scheduling non-blocking initial sync for "
432 << ModelTypeToString(model_type); 415 << ModelTypeToString(model_type);
433 nudge_tracker_.RecordInitialSyncRequired(model_type); 416 nudge_tracker_.RecordInitialSyncRequired(model_type);
(...skipping 14 matching lines...) Expand all
448 return; 431 return;
449 } 432 }
450 433
451 SDVLOG_LOC(nudge_location, 2) << "In ScheduleNudgeImpl with delay " 434 SDVLOG_LOC(nudge_location, 2) << "In ScheduleNudgeImpl with delay "
452 << delay.InMilliseconds() << " ms"; 435 << delay.InMilliseconds() << " ms";
453 436
454 if (!CanRunNudgeJobNow(NORMAL_PRIORITY)) 437 if (!CanRunNudgeJobNow(NORMAL_PRIORITY))
455 return; 438 return;
456 439
457 TimeTicks incoming_run_time = TimeTicks::Now() + delay; 440 TimeTicks incoming_run_time = TimeTicks::Now() + delay;
458 if (!scheduled_nudge_time_.is_null() && 441 if (pending_wakeup_timer_.IsRunning() &&
459 (scheduled_nudge_time_ < incoming_run_time)) { 442 (pending_wakeup_timer_.desired_run_time() < incoming_run_time)) {
460 // Old job arrives sooner than this one. Don't reschedule it. 443 // Old job arrives sooner than this one. Don't reschedule it.
461 return; 444 return;
462 } 445 }
463 446
464 // Either there is no existing nudge in flight or the incoming nudge should be 447 // Either there is no existing nudge in flight or the incoming nudge should be
465 // made to arrive first (preempt) the existing nudge. We reschedule in either 448 // made to arrive first (preempt) the existing nudge. We reschedule in either
466 // case. 449 // case.
467 SDVLOG_LOC(nudge_location, 2) << "Scheduling a nudge with " 450 SDVLOG_LOC(nudge_location, 2) << "Scheduling a nudge with "
468 << delay.InMilliseconds() << " ms delay"; 451 << delay.InMilliseconds() << " ms delay";
469 scheduled_nudge_time_ = incoming_run_time;
470 pending_wakeup_timer_.Start( 452 pending_wakeup_timer_.Start(
471 nudge_location, delay, base::Bind(&SyncSchedulerImpl::PerformDelayedNudge, 453 nudge_location, delay, base::Bind(&SyncSchedulerImpl::PerformDelayedNudge,
472 weak_ptr_factory_.GetWeakPtr())); 454 weak_ptr_factory_.GetWeakPtr()));
473 } 455 }
474 456
475 const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) { 457 const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) {
476 switch (mode) { 458 switch (mode) {
477 ENUM_CASE(CONFIGURATION_MODE); 459 ENUM_CASE(CONFIGURATION_MODE);
478 ENUM_CASE(CLEAR_SERVER_DATA_MODE); 460 ENUM_CASE(CLEAR_SERVER_DATA_MODE);
479 ENUM_CASE(NORMAL_MODE); 461 ENUM_CASE(NORMAL_MODE);
480 } 462 }
481 return ""; 463 return "";
482 } 464 }
483 465
484 void SyncSchedulerImpl::SetDefaultNudgeDelay(base::TimeDelta delay_ms) { 466 void SyncSchedulerImpl::SetDefaultNudgeDelay(TimeDelta delay_ms) {
485 DCHECK(CalledOnValidThread()); 467 DCHECK(CalledOnValidThread());
486 nudge_tracker_.SetDefaultNudgeDelay(delay_ms); 468 nudge_tracker_.SetDefaultNudgeDelay(delay_ms);
487 } 469 }
488 470
489 void SyncSchedulerImpl::DoNudgeSyncCycleJob(JobPriority priority) { 471 void SyncSchedulerImpl::DoNudgeSyncCycleJob(JobPriority priority) {
490 DCHECK(CalledOnValidThread()); 472 DCHECK(CalledOnValidThread());
491 DCHECK(CanRunNudgeJobNow(priority)); 473 DCHECK(CanRunNudgeJobNow(priority));
492 474
493 DVLOG(2) << "Will run normal mode sync cycle with types " 475 DVLOG(2) << "Will run normal mode sync cycle with types "
494 << ModelTypeSetToString(cycle_context_->GetEnabledTypes()); 476 << ModelTypeSetToString(cycle_context_->GetEnabledTypes());
495 std::unique_ptr<SyncCycle> cycle(SyncCycle::Build(cycle_context_, this)); 477 std::unique_ptr<SyncCycle> cycle(SyncCycle::Build(cycle_context_, this));
496 bool success = syncer_->NormalSyncShare(GetEnabledAndUnthrottledTypes(), 478 bool success = syncer_->NormalSyncShare(GetEnabledAndUnblockedTypes(),
497 &nudge_tracker_, cycle.get()); 479 &nudge_tracker_, cycle.get());
498 480
499 if (success) { 481 if (success) {
500 // That cycle took care of any outstanding work we had. 482 // That cycle took care of any outstanding work we had.
501 SDVLOG(2) << "Nudge succeeded."; 483 SDVLOG(2) << "Nudge succeeded.";
502 nudge_tracker_.RecordSuccessfulSyncCycle(); 484 nudge_tracker_.RecordSuccessfulSyncCycle();
503 scheduled_nudge_time_ = base::TimeTicks();
504 HandleSuccess(); 485 HandleSuccess();
505 486
506 // If this was a canary, we may need to restart the poll timer (the poll 487 // If this was a canary, we may need to restart the poll timer (the poll
507 // timer may have fired while the scheduler was in an error state, ignoring 488 // timer may have fired while the scheduler was in an error state, ignoring
508 // the poll). 489 // the poll).
509 if (!poll_timer_.IsRunning()) { 490 if (!poll_timer_.IsRunning()) {
510 SDVLOG(1) << "Canary succeeded, restarting polling."; 491 SDVLOG(1) << "Canary succeeded, restarting polling.";
511 AdjustPolling(UPDATE_INTERVAL); 492 AdjustPolling(UPDATE_INTERVAL);
512 } 493 }
513 } else { 494 } else {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 wait_interval_ = base::MakeUnique<WaitInterval>( 575 wait_interval_ = base::MakeUnique<WaitInterval>(
595 WaitInterval::EXPONENTIAL_BACKOFF, length); 576 WaitInterval::EXPONENTIAL_BACKOFF, length);
596 SDVLOG(2) << "Sync cycle failed. Will back off for " 577 SDVLOG(2) << "Sync cycle failed. Will back off for "
597 << wait_interval_->length.InMilliseconds() << "ms."; 578 << wait_interval_->length.InMilliseconds() << "ms.";
598 } 579 }
599 RestartWaiting(); 580 RestartWaiting();
600 } 581 }
601 582
602 void SyncSchedulerImpl::DoPollSyncCycleJob() { 583 void SyncSchedulerImpl::DoPollSyncCycleJob() {
603 SDVLOG(2) << "Polling with types " 584 SDVLOG(2) << "Polling with types "
604 << ModelTypeSetToString(GetEnabledAndUnthrottledTypes()); 585 << ModelTypeSetToString(GetEnabledAndUnblockedTypes());
605 std::unique_ptr<SyncCycle> cycle(SyncCycle::Build(cycle_context_, this)); 586 std::unique_ptr<SyncCycle> cycle(SyncCycle::Build(cycle_context_, this));
606 bool success = 587 bool success =
607 syncer_->PollSyncShare(GetEnabledAndUnthrottledTypes(), cycle.get()); 588 syncer_->PollSyncShare(GetEnabledAndUnblockedTypes(), cycle.get());
608 589
609 // Only restart the timer if the poll succeeded. Otherwise rely on normal 590 // Only restart the timer if the poll succeeded. Otherwise rely on normal
610 // failure handling to retry with backoff. 591 // failure handling to retry with backoff.
611 if (success) { 592 if (success) {
612 AdjustPolling(FORCE_RESET); 593 AdjustPolling(FORCE_RESET);
613 HandleSuccess(); 594 HandleSuccess();
614 } else { 595 } else {
615 HandleFailure(cycle->status_controller().model_neutral_state()); 596 HandleFailure(cycle->status_controller().model_neutral_state());
616 } 597 }
617 } 598 }
618 599
619 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { 600 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) {
620 DCHECK(CalledOnValidThread()); 601 DCHECK(CalledOnValidThread());
621 base::TimeTicks now = TimeTicks::Now(); 602 TimeTicks now = TimeTicks::Now();
622 // Update timing information for how often datatypes are triggering nudges. 603 // Update timing information for how often datatypes are triggering nudges.
623 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { 604 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) {
624 base::TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()]; 605 TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()];
625 last_local_nudges_by_model_type_[iter.Get()] = now; 606 last_local_nudges_by_model_type_[iter.Get()] = now;
626 if (previous.is_null()) 607 if (previous.is_null())
627 continue; 608 continue;
628 609
629 #define PER_DATA_TYPE_MACRO(type_str) \ 610 #define PER_DATA_TYPE_MACRO(type_str) \
630 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); 611 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous);
631 SYNC_DATA_TYPE_HISTOGRAM(iter.Get()); 612 SYNC_DATA_TYPE_HISTOGRAM(iter.Get());
632 #undef PER_DATA_TYPE_MACRO 613 #undef PER_DATA_TYPE_MACRO
633 } 614 }
634 } 615 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 658
678 SDVLOG(1) << "Updating polling delay to " << poll_delay.InMinutes() 659 SDVLOG(1) << "Updating polling delay to " << poll_delay.InMinutes()
679 << " minutes."; 660 << " minutes.";
680 661
681 // Adjust poll rate. Start will reset the timer if it was already running. 662 // Adjust poll rate. Start will reset the timer if it was already running.
682 poll_timer_.Start(FROM_HERE, poll_delay, this, 663 poll_timer_.Start(FROM_HERE, poll_delay, this,
683 &SyncSchedulerImpl::PollTimerCallback); 664 &SyncSchedulerImpl::PollTimerCallback);
684 } 665 }
685 666
686 void SyncSchedulerImpl::RestartWaiting() { 667 void SyncSchedulerImpl::RestartWaiting() {
687 CHECK(wait_interval_.get()); 668 if (wait_interval_.get()) {
688 DCHECK(wait_interval_->length >= TimeDelta::FromSeconds(0)); 669 // Global throttling or backoff
689 NotifyRetryTime(base::Time::Now() + wait_interval_->length); 670 NotifyRetryTime(base::Time::Now() + wait_interval_->length);
690 SDVLOG(2) << "Starting WaitInterval timer of length " 671 SDVLOG(2) << "Starting WaitInterval timer of length "
691 << wait_interval_->length.InMilliseconds() << "ms."; 672 << wait_interval_->length.InMilliseconds() << "ms.";
692 if (wait_interval_->mode == WaitInterval::THROTTLED) { 673 if (wait_interval_->mode == WaitInterval::THROTTLED) {
693 pending_wakeup_timer_.Start(FROM_HERE, wait_interval_->length, 674 pending_wakeup_timer_.Start(FROM_HERE, wait_interval_->length,
694 base::Bind(&SyncSchedulerImpl::Unthrottle, 675 base::Bind(&SyncSchedulerImpl::Unthrottle,
676 weak_ptr_factory_.GetWeakPtr()));
677 } else {
678 pending_wakeup_timer_.Start(
679 FROM_HERE, wait_interval_->length,
680 base::Bind(&SyncSchedulerImpl::ExponentialBackoffRetry,
681 weak_ptr_factory_.GetWeakPtr()));
682 }
683 } else if (nudge_tracker_.IsAnyTypeBlocked()) {
684 // Per-datatype throttled or backed off.
685 TimeDelta time_until_next_unblock =
686 nudge_tracker_.GetTimeUntilNextUnblock();
687 pending_wakeup_timer_.Start(FROM_HERE, time_until_next_unblock,
688 base::Bind(&SyncSchedulerImpl::OnTypesUnblocked,
695 weak_ptr_factory_.GetWeakPtr())); 689 weak_ptr_factory_.GetWeakPtr()));
696 } else {
697 pending_wakeup_timer_.Start(
698 FROM_HERE, wait_interval_->length,
699 base::Bind(&SyncSchedulerImpl::ExponentialBackoffRetry,
700 weak_ptr_factory_.GetWeakPtr()));
701 } 690 }
702 } 691 }
703 692
704 void SyncSchedulerImpl::Stop() { 693 void SyncSchedulerImpl::Stop() {
705 DCHECK(CalledOnValidThread()); 694 DCHECK(CalledOnValidThread());
706 SDVLOG(2) << "Stop called"; 695 SDVLOG(2) << "Stop called";
707 696
708 // Kill any in-flight method calls. 697 // Kill any in-flight method calls.
709 weak_ptr_factory_.InvalidateWeakPtrs(); 698 weak_ptr_factory_.InvalidateWeakPtrs();
710 wait_interval_.reset(); 699 wait_interval_.reset();
(...skipping 19 matching lines...) Expand all
730 // access token will be here. 719 // access token will be here.
731 base::ThreadTaskRunnerHandle::Get()->PostTask( 720 base::ThreadTaskRunnerHandle::Get()->PostTask(
732 FROM_HERE, base::Bind(&SyncSchedulerImpl::TrySyncCycleJobImpl, 721 FROM_HERE, base::Bind(&SyncSchedulerImpl::TrySyncCycleJobImpl,
733 weak_ptr_factory_.GetWeakPtr())); 722 weak_ptr_factory_.GetWeakPtr()));
734 } 723 }
735 724
736 void SyncSchedulerImpl::TrySyncCycleJobImpl() { 725 void SyncSchedulerImpl::TrySyncCycleJobImpl() {
737 JobPriority priority = next_sync_cycle_job_priority_; 726 JobPriority priority = next_sync_cycle_job_priority_;
738 next_sync_cycle_job_priority_ = NORMAL_PRIORITY; 727 next_sync_cycle_job_priority_ = NORMAL_PRIORITY;
739 728
740 nudge_tracker_.SetSyncCycleStartTime(base::TimeTicks::Now()); 729 nudge_tracker_.SetSyncCycleStartTime(TimeTicks::Now());
741 730
742 DCHECK(CalledOnValidThread()); 731 DCHECK(CalledOnValidThread());
743 if (mode_ == CONFIGURATION_MODE) { 732 if (mode_ == CONFIGURATION_MODE) {
744 if (pending_configure_params_) { 733 if (pending_configure_params_) {
745 SDVLOG(2) << "Found pending configure job"; 734 SDVLOG(2) << "Found pending configure job";
746 DoConfigurationSyncCycleJob(priority); 735 DoConfigurationSyncCycleJob(priority);
747 } 736 }
748 } else if (mode_ == CLEAR_SERVER_DATA_MODE) { 737 } else if (mode_ == CLEAR_SERVER_DATA_MODE) {
749 if (pending_clear_params_) { 738 if (pending_clear_params_) {
750 DoClearServerDataSyncCycleJob(priority); 739 DoClearServerDataSyncCycleJob(priority);
751 } 740 }
752 } else if (CanRunNudgeJobNow(priority)) { 741 } else if (CanRunNudgeJobNow(priority)) {
753 if (nudge_tracker_.IsSyncRequired()) { 742 if (nudge_tracker_.IsSyncRequired()) {
754 SDVLOG(2) << "Found pending nudge job"; 743 SDVLOG(2) << "Found pending nudge job";
755 DoNudgeSyncCycleJob(priority); 744 DoNudgeSyncCycleJob(priority);
756 } else if (((base::TimeTicks::Now() - last_poll_reset_) >= 745 } else if (((TimeTicks::Now() - last_poll_reset_) >= GetPollInterval())) {
757 GetPollInterval())) {
758 SDVLOG(2) << "Found pending poll"; 746 SDVLOG(2) << "Found pending poll";
759 DoPollSyncCycleJob(); 747 DoPollSyncCycleJob();
760 } 748 }
761 } else { 749 } else {
762 // We must be in an error state. Transitioning out of each of these 750 // We must be in an error state. Transitioning out of each of these
763 // error states should trigger a canary job. 751 // error states should trigger a canary job.
764 DCHECK(IsCurrentlyThrottled() || IsBackingOff() || 752 DCHECK(IsCurrentlyThrottled() || IsBackingOff() ||
765 cycle_context_->connection_manager()->HasInvalidAuthToken()); 753 cycle_context_->connection_manager()->HasInvalidAuthToken());
766 } 754 }
767 755
(...skipping 21 matching lines...) Expand all
789 TrySyncCycleJob(); 777 TrySyncCycleJob();
790 } 778 }
791 779
792 void SyncSchedulerImpl::Unthrottle() { 780 void SyncSchedulerImpl::Unthrottle() {
793 DCHECK(CalledOnValidThread()); 781 DCHECK(CalledOnValidThread());
794 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode); 782 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode);
795 783
796 // We're no longer throttled, so clear the wait interval. 784 // We're no longer throttled, so clear the wait interval.
797 wait_interval_.reset(); 785 wait_interval_.reset();
798 NotifyRetryTime(base::Time()); 786 NotifyRetryTime(base::Time());
799 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); 787 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes());
800 788
801 // We treat this as a 'canary' in the sense that it was originally scheduled 789 // We treat this as a 'canary' in the sense that it was originally scheduled
802 // to run some time ago, failed, and we now want to retry, versus a job that 790 // to run some time ago, failed, and we now want to retry, versus a job that
803 // was just created (e.g via ScheduleNudgeImpl). The main implication is 791 // was just created (e.g via ScheduleNudgeImpl). The main implication is
804 // that we're careful to update routing info (etc) with such potentially 792 // that we're careful to update routing info (etc) with such potentially
805 // stale canary jobs. 793 // stale canary jobs.
806 TryCanaryJob(); 794 TryCanaryJob();
807 } 795 }
808 796
809 void SyncSchedulerImpl::TypeUnthrottle(base::TimeTicks unthrottle_time) { 797 void SyncSchedulerImpl::OnTypesUnblocked() {
810 DCHECK(CalledOnValidThread()); 798 DCHECK(CalledOnValidThread());
811 nudge_tracker_.UpdateTypeThrottlingState(unthrottle_time); 799 nudge_tracker_.UpdateTypeThrottlingAndBackoffState();
812 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); 800 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes());
813 801
814 if (nudge_tracker_.IsAnyTypeThrottled()) { 802 RestartWaiting();
815 const base::TimeTicks now = base::TimeTicks::Now();
816 base::TimeDelta time_until_next_unthrottle =
817 nudge_tracker_.GetTimeUntilNextUnthrottle(now);
818 type_unthrottle_timer_.Start(FROM_HERE, time_until_next_unthrottle,
819 base::Bind(&SyncSchedulerImpl::TypeUnthrottle,
820 weak_ptr_factory_.GetWeakPtr(),
821 now + time_until_next_unthrottle));
822 }
823 803
824 // Maybe this is a good time to run a nudge job. Let's try it. 804 // Maybe this is a good time to run a nudge job. Let's try it.
825 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) 805 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY))
826 TrySyncCycleJob(); 806 TrySyncCycleJob();
827 } 807 }
828 808
829 void SyncSchedulerImpl::PerformDelayedNudge() { 809 void SyncSchedulerImpl::PerformDelayedNudge() {
830 // Circumstances may have changed since we scheduled this delayed nudge. 810 // Circumstances may have changed since we scheduled this delayed nudge.
831 // We must check to see if it's OK to run the job before we do so. 811 // We must check to see if it's OK to run the job before we do so.
832 if (CanRunNudgeJobNow(NORMAL_PRIORITY)) 812 if (CanRunNudgeJobNow(NORMAL_PRIORITY))
833 TrySyncCycleJob(); 813 TrySyncCycleJob();
834 814
835 // We're not responsible for setting up any retries here. The functions that 815 // We're not responsible for setting up any retries here. The functions that
836 // first put us into a state that prevents successful sync cycles (eg. global 816 // first put us into a state that prevents successful sync cycles (eg. global
837 // throttling, type throttling, network errors, transient errors) will also 817 // throttling, type throttling, network errors, transient errors) will also
838 // setup the appropriate retry logic (eg. retry after timeout, exponential 818 // setup the appropriate retry logic (eg. retry after timeout, exponential
839 // backoff, retry when the network changes). 819 // backoff, retry when the network changes).
840 } 820 }
841 821
842 void SyncSchedulerImpl::ExponentialBackoffRetry() { 822 void SyncSchedulerImpl::ExponentialBackoffRetry() {
843 TryCanaryJob(); 823 TryCanaryJob();
844 } 824 }
845 825
846 void SyncSchedulerImpl::NotifyRetryTime(base::Time retry_time) { 826 void SyncSchedulerImpl::NotifyRetryTime(base::Time retry_time) {
847 for (auto& observer : *cycle_context_->listeners()) 827 for (auto& observer : *cycle_context_->listeners())
848 observer.OnRetryTimeChanged(retry_time); 828 observer.OnRetryTimeChanged(retry_time);
849 } 829 }
850 830
851 void SyncSchedulerImpl::NotifyThrottledTypesChanged(ModelTypeSet types) { 831 void SyncSchedulerImpl::NotifyBlockedTypesChanged(ModelTypeSet types) {
852 for (auto& observer : *cycle_context_->listeners()) 832 ModelTypeSet throttled_types;
853 observer.OnThrottledTypesChanged(types); 833 ModelTypeSet backed_off_types;
834 for (ModelTypeSet::Iterator type_it = types.First(); type_it.Good();
835 type_it.Inc()) {
836 if (nudge_tracker_.GetTypeBlockingMode(type_it.Get()) ==
837 WaitInterval::THROTTLED) {
838 throttled_types.Put(type_it.Get());
839 } else if (nudge_tracker_.GetTypeBlockingMode(type_it.Get()) ==
840 WaitInterval::EXPONENTIAL_BACKOFF) {
841 backed_off_types.Put(type_it.Get());
842 }
843 }
844
845 for (auto& observer : *cycle_context_->listeners()) {
846 observer.OnThrottledTypesChanged(throttled_types);
847 observer.OnBackedOffTypesChanged(backed_off_types);
848 }
854 } 849 }
855 850
856 bool SyncSchedulerImpl::IsBackingOff() const { 851 bool SyncSchedulerImpl::IsBackingOff() const {
857 DCHECK(CalledOnValidThread()); 852 DCHECK(CalledOnValidThread());
858 return wait_interval_.get() && 853 return wait_interval_.get() &&
859 wait_interval_->mode == WaitInterval::EXPONENTIAL_BACKOFF; 854 wait_interval_->mode == WaitInterval::EXPONENTIAL_BACKOFF;
860 } 855 }
861 856
862 void SyncSchedulerImpl::OnThrottled(const base::TimeDelta& throttle_duration) { 857 void SyncSchedulerImpl::OnThrottled(const TimeDelta& throttle_duration) {
863 DCHECK(CalledOnValidThread()); 858 DCHECK(CalledOnValidThread());
864 wait_interval_ = base::MakeUnique<WaitInterval>(WaitInterval::THROTTLED, 859 wait_interval_ = base::MakeUnique<WaitInterval>(WaitInterval::THROTTLED,
865 throttle_duration); 860 throttle_duration);
866 NotifyRetryTime(base::Time::Now() + wait_interval_->length); 861 NotifyRetryTime(base::Time::Now() + wait_interval_->length);
867 NotifyThrottledTypesChanged(ModelTypeSet::All()); 862
863 for (auto& observer : *cycle_context_->listeners()) {
864 observer.OnThrottledTypesChanged(ModelTypeSet::All());
865 }
868 } 866 }
869 867
870 void SyncSchedulerImpl::OnTypesThrottled( 868 void SyncSchedulerImpl::OnTypesThrottled(ModelTypeSet types,
871 ModelTypeSet types, 869 const TimeDelta& throttle_duration) {
872 const base::TimeDelta& throttle_duration) { 870 TimeTicks now = TimeTicks::Now();
873 base::TimeTicks now = base::TimeTicks::Now();
874 871
875 SDVLOG(1) << "Throttling " << ModelTypeSetToString(types) << " for " 872 SDVLOG(1) << "Throttling " << ModelTypeSetToString(types) << " for "
876 << throttle_duration.InMinutes() << " minutes."; 873 << throttle_duration.InMinutes() << " minutes.";
877 874
878 nudge_tracker_.SetTypesThrottledUntil(types, throttle_duration, now); 875 nudge_tracker_.SetTypesThrottledUntil(types, throttle_duration, now);
879 base::TimeDelta time_until_next_unthrottle = 876 RestartWaiting();
880 nudge_tracker_.GetTimeUntilNextUnthrottle(now); 877 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes());
881 type_unthrottle_timer_.Start(FROM_HERE, time_until_next_unthrottle, 878 }
882 base::Bind(&SyncSchedulerImpl::TypeUnthrottle, 879
883 weak_ptr_factory_.GetWeakPtr(), 880 void SyncSchedulerImpl::OnTypesBackedOff(ModelTypeSet types) {
884 now + time_until_next_unthrottle)); 881 TimeTicks now = TimeTicks::Now();
885 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); 882
883 for (ModelTypeSet::Iterator type = types.First(); type.Good(); type.Inc()) {
884 TimeDelta last_backoff_time =
885 TimeDelta::FromSeconds(kInitialBackoffRetrySeconds);
886 if (nudge_tracker_.GetTypeBlockingMode(type.Get()) ==
887 WaitInterval::EXPONENTIAL_BACKOFF_RETRYING) {
888 last_backoff_time = nudge_tracker_.GetTypeLastBackoffInterval(type.Get());
889 }
890
891 TimeDelta length = delay_provider_->GetDelay(last_backoff_time);
892 nudge_tracker_.SetTypeBackedOff(type.Get(), length, now);
893 SDVLOG(1) << "Backing off " << ModelTypeToString(type.Get()) << " for "
894 << length.InSeconds() << " second.";
895 }
896 RestartWaiting();
897 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes());
886 } 898 }
887 899
888 bool SyncSchedulerImpl::IsCurrentlyThrottled() { 900 bool SyncSchedulerImpl::IsCurrentlyThrottled() {
889 DCHECK(CalledOnValidThread()); 901 DCHECK(CalledOnValidThread());
890 return wait_interval_.get() && 902 return wait_interval_.get() &&
891 wait_interval_->mode == WaitInterval::THROTTLED; 903 wait_interval_->mode == WaitInterval::THROTTLED;
892 } 904 }
893 905
894 void SyncSchedulerImpl::OnReceivedShortPollIntervalUpdate( 906 void SyncSchedulerImpl::OnReceivedShortPollIntervalUpdate(
895 const base::TimeDelta& new_interval) { 907 const TimeDelta& new_interval) {
896 DCHECK(CalledOnValidThread()); 908 DCHECK(CalledOnValidThread());
897 if (new_interval == syncer_short_poll_interval_seconds_) 909 if (new_interval == syncer_short_poll_interval_seconds_)
898 return; 910 return;
899 SDVLOG(1) << "Updating short poll interval to " << new_interval.InMinutes() 911 SDVLOG(1) << "Updating short poll interval to " << new_interval.InMinutes()
900 << " minutes."; 912 << " minutes.";
901 syncer_short_poll_interval_seconds_ = new_interval; 913 syncer_short_poll_interval_seconds_ = new_interval;
902 AdjustPolling(UPDATE_INTERVAL); 914 AdjustPolling(UPDATE_INTERVAL);
903 } 915 }
904 916
905 void SyncSchedulerImpl::OnReceivedLongPollIntervalUpdate( 917 void SyncSchedulerImpl::OnReceivedLongPollIntervalUpdate(
906 const base::TimeDelta& new_interval) { 918 const TimeDelta& new_interval) {
907 DCHECK(CalledOnValidThread()); 919 DCHECK(CalledOnValidThread());
908 if (new_interval == syncer_long_poll_interval_seconds_) 920 if (new_interval == syncer_long_poll_interval_seconds_)
909 return; 921 return;
910 SDVLOG(1) << "Updating long poll interval to " << new_interval.InMinutes() 922 SDVLOG(1) << "Updating long poll interval to " << new_interval.InMinutes()
911 << " minutes."; 923 << " minutes.";
912 syncer_long_poll_interval_seconds_ = new_interval; 924 syncer_long_poll_interval_seconds_ = new_interval;
913 AdjustPolling(UPDATE_INTERVAL); 925 AdjustPolling(UPDATE_INTERVAL);
914 } 926 }
915 927
916 void SyncSchedulerImpl::OnReceivedCustomNudgeDelays( 928 void SyncSchedulerImpl::OnReceivedCustomNudgeDelays(
917 const std::map<ModelType, base::TimeDelta>& nudge_delays) { 929 const std::map<ModelType, TimeDelta>& nudge_delays) {
918 DCHECK(CalledOnValidThread()); 930 DCHECK(CalledOnValidThread());
919 nudge_tracker_.OnReceivedCustomNudgeDelays(nudge_delays); 931 nudge_tracker_.OnReceivedCustomNudgeDelays(nudge_delays);
920 } 932 }
921 933
922 void SyncSchedulerImpl::OnReceivedClientInvalidationHintBufferSize(int size) { 934 void SyncSchedulerImpl::OnReceivedClientInvalidationHintBufferSize(int size) {
923 if (size > 0) 935 if (size > 0)
924 nudge_tracker_.SetHintBufferSize(size); 936 nudge_tracker_.SetHintBufferSize(size);
925 else 937 else
926 NOTREACHED() << "Hint buffer size should be > 0."; 938 NOTREACHED() << "Hint buffer size should be > 0.";
927 } 939 }
928 940
929 void SyncSchedulerImpl::OnSyncProtocolError( 941 void SyncSchedulerImpl::OnSyncProtocolError(
930 const SyncProtocolError& sync_protocol_error) { 942 const SyncProtocolError& sync_protocol_error) {
931 DCHECK(CalledOnValidThread()); 943 DCHECK(CalledOnValidThread());
932 if (ShouldRequestEarlyExit(sync_protocol_error)) { 944 if (ShouldRequestEarlyExit(sync_protocol_error)) {
933 SDVLOG(2) << "Sync Scheduler requesting early exit."; 945 SDVLOG(2) << "Sync Scheduler requesting early exit.";
934 Stop(); 946 Stop();
935 } 947 }
936 if (IsActionableError(sync_protocol_error)) { 948 if (IsActionableError(sync_protocol_error)) {
937 SDVLOG(2) << "OnActionableError"; 949 SDVLOG(2) << "OnActionableError";
938 for (auto& observer : *cycle_context_->listeners()) 950 for (auto& observer : *cycle_context_->listeners())
939 observer.OnActionableError(sync_protocol_error); 951 observer.OnActionableError(sync_protocol_error);
940 } 952 }
941 } 953 }
942 954
943 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const base::TimeDelta& delay) { 955 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const TimeDelta& delay) {
944 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + delay); 956 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + delay);
945 retry_timer_.Start(FROM_HERE, delay, this, 957 retry_timer_.Start(FROM_HERE, delay, this,
946 &SyncSchedulerImpl::RetryTimerCallback); 958 &SyncSchedulerImpl::RetryTimerCallback);
947 } 959 }
948 960
949 void SyncSchedulerImpl::OnReceivedMigrationRequest(ModelTypeSet types) { 961 void SyncSchedulerImpl::OnReceivedMigrationRequest(ModelTypeSet types) {
950 for (auto& observer : *cycle_context_->listeners()) 962 for (auto& observer : *cycle_context_->listeners())
951 observer.OnMigrationRequested(types); 963 observer.OnMigrationRequested(types);
952 } 964 }
953 965
954 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { 966 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) {
955 DCHECK(CalledOnValidThread()); 967 DCHECK(CalledOnValidThread());
956 cycle_context_->set_notifications_enabled(notifications_enabled); 968 cycle_context_->set_notifications_enabled(notifications_enabled);
957 if (notifications_enabled) 969 if (notifications_enabled)
958 nudge_tracker_.OnInvalidationsEnabled(); 970 nudge_tracker_.OnInvalidationsEnabled();
959 else 971 else
960 nudge_tracker_.OnInvalidationsDisabled(); 972 nudge_tracker_.OnInvalidationsDisabled();
961 } 973 }
962 974
963 #undef SDVLOG_LOC 975 #undef SDVLOG_LOC
964 976
965 #undef SDVLOG 977 #undef SDVLOG
966 978
967 #undef SLOG 979 #undef SLOG
968 980
969 #undef ENUM_CASE 981 #undef ENUM_CASE
970 982
971 } // namespace syncer 983 } // namespace syncer
OLDNEW
« no previous file with comments | « components/sync/engine_impl/sync_scheduler_impl.h ('k') | components/sync/engine_impl/sync_scheduler_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698