Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "sync/engine/sync_scheduler_impl.h" | 5 #include "sync/engine/sync_scheduler_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 | 9 |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 336 } | 336 } |
| 337 | 337 |
| 338 return true; | 338 return true; |
| 339 } | 339 } |
| 340 | 340 |
| 341 SyncSchedulerImpl::JobProcessDecision | 341 SyncSchedulerImpl::JobProcessDecision |
| 342 SyncSchedulerImpl::DecideWhileInWaitInterval(const SyncSessionJob& job, | 342 SyncSchedulerImpl::DecideWhileInWaitInterval(const SyncSessionJob& job, |
| 343 JobPriority priority) { | 343 JobPriority priority) { |
| 344 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 344 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 345 DCHECK(wait_interval_.get()); | 345 DCHECK(wait_interval_.get()); |
| 346 DCHECK_NE(job.purpose(), SyncSessionJob::POLL); | |
| 346 | 347 |
| 347 SDVLOG(2) << "DecideWhileInWaitInterval with WaitInterval mode " | 348 SDVLOG(2) << "DecideWhileInWaitInterval with WaitInterval mode " |
| 348 << WaitInterval::GetModeString(wait_interval_->mode) | 349 << WaitInterval::GetModeString(wait_interval_->mode) |
| 349 << (wait_interval_->had_nudge ? " (had nudge)" : "") | 350 << (wait_interval_->had_nudge ? " (had nudge)" : "") |
| 350 << ((priority == CANARY_PRIORITY) ? " (canary)" : ""); | 351 << ((priority == CANARY_PRIORITY) ? " (canary)" : ""); |
| 351 | 352 |
| 352 if (job.purpose() == SyncSessionJob::POLL) | |
| 353 return DROP; | |
| 354 | |
| 355 // If we save a job while in a WaitInterval, there is a well-defined moment | 353 // If we save a job while in a WaitInterval, there is a well-defined moment |
| 356 // in time in the future when it makes sense for that SAVE-worthy job to try | 354 // in time in the future when it makes sense for that SAVE-worthy job to try |
| 357 // running again -- the end of the WaitInterval. | 355 // running again -- the end of the WaitInterval. |
| 358 DCHECK(job.purpose() == SyncSessionJob::NUDGE || | 356 DCHECK(job.purpose() == SyncSessionJob::NUDGE || |
| 359 job.purpose() == SyncSessionJob::CONFIGURATION); | 357 job.purpose() == SyncSessionJob::CONFIGURATION); |
| 360 | 358 |
| 361 // If throttled, there's a clock ticking to unthrottle. We want to get | 359 // If throttled, there's a clock ticking to unthrottle. We want to get |
| 362 // on the same train. | 360 // on the same train. |
| 363 if (wait_interval_->mode == WaitInterval::THROTTLED) | 361 if (wait_interval_->mode == WaitInterval::THROTTLED) |
| 364 return SAVE; | 362 return SAVE; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 376 return CONTINUE; | 374 return CONTINUE; |
| 377 } | 375 } |
| 378 return (priority == CANARY_PRIORITY) ? CONTINUE : SAVE; | 376 return (priority == CANARY_PRIORITY) ? CONTINUE : SAVE; |
| 379 } | 377 } |
| 380 | 378 |
| 381 SyncSchedulerImpl::JobProcessDecision SyncSchedulerImpl::DecideOnJob( | 379 SyncSchedulerImpl::JobProcessDecision SyncSchedulerImpl::DecideOnJob( |
| 382 const SyncSessionJob& job, | 380 const SyncSessionJob& job, |
| 383 JobPriority priority) { | 381 JobPriority priority) { |
| 384 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 382 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 385 | 383 |
| 384 // POLL jobs do not call this function. | |
| 385 DCHECK(job.purpose() == SyncSessionJob::NUDGE || | |
| 386 job.purpose() == SyncSessionJob::CONFIGURATION); | |
| 387 | |
| 386 // See if our type is throttled. | 388 // See if our type is throttled. |
| 387 ModelTypeSet throttled_types = | 389 ModelTypeSet throttled_types = |
| 388 session_context_->throttled_data_type_tracker()->GetThrottledTypes(); | 390 session_context_->throttled_data_type_tracker()->GetThrottledTypes(); |
| 389 if (job.purpose() == SyncSessionJob::NUDGE && | 391 if (job.purpose() == SyncSessionJob::NUDGE && |
| 390 job.session()->source().updates_source == GetUpdatesCallerInfo::LOCAL) { | 392 job.session()->source().updates_source == GetUpdatesCallerInfo::LOCAL) { |
| 391 ModelTypeSet requested_types; | 393 ModelTypeSet requested_types; |
| 392 for (ModelTypeInvalidationMap::const_iterator i = | 394 for (ModelTypeInvalidationMap::const_iterator i = |
| 393 job.session()->source().types.begin(); | 395 job.session()->source().types.begin(); |
| 394 i != job.session()->source().types.end(); | 396 i != job.session()->source().types.end(); |
| 395 ++i) { | 397 ++i) { |
| 396 requested_types.Put(i->first); | 398 requested_types.Put(i->first); |
| 397 } | 399 } |
| 398 | 400 |
| 399 // If all types are throttled, do not CONTINUE. Today, we don't treat | 401 // If all types are throttled, do not CONTINUE. Today, we don't treat |
| 400 // a per-datatype "unthrottle" event as something that should force a | 402 // a per-datatype "unthrottle" event as something that should force a |
| 401 // canary job. For this reason, there's no good time to reschedule this job | 403 // canary job. For this reason, there's no good time to reschedule this job |
| 402 // to run -- we'll lazily wait for an independent event to trigger a sync. | 404 // to run -- we'll lazily wait for an independent event to trigger a sync. |
| 403 // Note that there may already be such an event if we're in a WaitInterval, | 405 // Note that there may already be such an event if we're in a WaitInterval, |
| 404 // so we can retry it then. | 406 // so we can retry it then. |
| 405 if (!requested_types.Empty() && throttled_types.HasAll(requested_types)) | 407 if (!requested_types.Empty() && throttled_types.HasAll(requested_types)) |
| 406 return DROP; // TODO(tim): Don't drop. http://crbug.com/177659 | 408 return DROP; // TODO(tim): Don't drop. http://crbug.com/177659 |
| 407 } | 409 } |
| 408 | 410 |
| 409 if (wait_interval_.get()) | 411 if (wait_interval_.get()) |
| 410 return DecideWhileInWaitInterval(job, priority); | 412 return DecideWhileInWaitInterval(job, priority); |
| 411 | 413 |
| 412 if (mode_ == CONFIGURATION_MODE) { | 414 if (mode_ == CONFIGURATION_MODE) { |
| 413 if (job.purpose() == SyncSessionJob::NUDGE) | 415 if (job.purpose() == SyncSessionJob::NUDGE) |
| 414 return SAVE; // Running requires a mode switch. | 416 return SAVE; // Running requires a mode switch. |
| 415 else if (job.purpose() == SyncSessionJob::CONFIGURATION) | 417 else // job.purpose() == SyncSessionJob::CONFIGURATION |
| 416 return CONTINUE; | 418 return CONTINUE; |
| 417 else | |
| 418 return DROP; | |
| 419 } | 419 } |
| 420 | 420 |
| 421 // We are in normal mode. | 421 // We are in normal mode. |
| 422 DCHECK_EQ(mode_, NORMAL_MODE); | 422 DCHECK_EQ(mode_, NORMAL_MODE); |
| 423 DCHECK_NE(job.purpose(), SyncSessionJob::CONFIGURATION); | 423 DCHECK_NE(job.purpose(), SyncSessionJob::CONFIGURATION); |
| 424 | 424 |
| 425 // Note about some subtle scheduling semantics. | 425 // Note about some subtle scheduling semantics. |
| 426 // | 426 // |
| 427 // It's possible at this point that |job| is known to be unnecessary, and | 427 // It's possible at this point that |job| is known to be unnecessary, and |
| 428 // dropping it would be perfectly safe and correct. Consider | 428 // dropping it would be perfectly safe and correct. Consider |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 SDVLOG(1) << "Not posting task as scheduler is stopped."; | 676 SDVLOG(1) << "Not posting task as scheduler is stopped."; |
| 677 return; | 677 return; |
| 678 } | 678 } |
| 679 sync_loop_->PostDelayedTask(from_here, task, delay); | 679 sync_loop_->PostDelayedTask(from_here, task, delay); |
| 680 } | 680 } |
| 681 | 681 |
| 682 void SyncSchedulerImpl::ScheduleSyncSessionJob( | 682 void SyncSchedulerImpl::ScheduleSyncSessionJob( |
| 683 const tracked_objects::Location& loc, | 683 const tracked_objects::Location& loc, |
| 684 scoped_ptr<SyncSessionJob> job) { | 684 scoped_ptr<SyncSessionJob> job) { |
| 685 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 685 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 686 DCHECK_EQ(job->purpose(), SyncSessionJob::NUDGE); | |
| 686 if (no_scheduling_allowed_) { | 687 if (no_scheduling_allowed_) { |
| 687 NOTREACHED() << "Illegal to schedule job while session in progress."; | 688 NOTREACHED() << "Illegal to schedule job while session in progress."; |
| 688 return; | 689 return; |
| 689 } | 690 } |
| 690 | 691 |
| 691 TimeDelta delay = job->scheduled_start() - TimeTicks::Now(); | 692 TimeDelta delay = job->scheduled_start() - TimeTicks::Now(); |
| 692 if (delay < TimeDelta::FromMilliseconds(0)) | 693 if (delay < TimeDelta::FromMilliseconds(0)) |
| 693 delay = TimeDelta::FromMilliseconds(0); | 694 delay = TimeDelta::FromMilliseconds(0); |
| 694 SDVLOG_LOC(loc, 2) | 695 SDVLOG_LOC(loc, 2) |
| 695 << "In ScheduleSyncSessionJob with " | 696 << "In ScheduleSyncSessionJob with " |
| 696 << SyncSessionJob::GetPurposeString(job->purpose()) | 697 << SyncSessionJob::GetPurposeString(job->purpose()) |
| 697 << " job and " << delay.InMilliseconds() << " ms delay"; | 698 << " job and " << delay.InMilliseconds() << " ms delay"; |
| 698 | 699 |
| 699 DCHECK(job->purpose() == SyncSessionJob::NUDGE || | 700 SDVLOG_LOC(loc, 2) << "Resetting pending_nudge to "; |
| 700 job->purpose() == SyncSessionJob::POLL); | 701 DCHECK(!pending_nudge_ || pending_nudge_->session() == |
| 701 if (job->purpose() == SyncSessionJob::NUDGE) { | 702 job->session()); |
| 702 SDVLOG_LOC(loc, 2) << "Resetting pending_nudge to "; | 703 pending_nudge_ = job.get(); |
| 703 DCHECK(!pending_nudge_ || pending_nudge_->session() == | |
| 704 job->session()); | |
| 705 pending_nudge_ = job.get(); | |
| 706 } | |
| 707 | 704 |
| 708 PostDelayedTask(loc, "DoSyncSessionJob", | 705 PostDelayedTask(loc, "DoSyncSessionJob", |
| 709 base::Bind(base::IgnoreResult(&SyncSchedulerImpl::DoSyncSessionJob), | 706 base::Bind(base::IgnoreResult(&SyncSchedulerImpl::DoSyncSessionJob), |
| 710 weak_ptr_factory_.GetWeakPtr(), | 707 weak_ptr_factory_.GetWeakPtr(), |
| 711 base::Passed(&job), | 708 base::Passed(&job), |
| 712 NORMAL_PRIORITY), | 709 NORMAL_PRIORITY), |
| 713 delay); | 710 delay); |
| 714 } | 711 } |
| 715 | 712 |
| 716 bool SyncSchedulerImpl::DoSyncSessionJob(scoped_ptr<SyncSessionJob> job, | 713 bool SyncSchedulerImpl::DoSyncSessionJob(scoped_ptr<SyncSessionJob> job, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 749 return false; | 746 return false; |
| 750 } | 747 } |
| 751 | 748 |
| 752 SDVLOG(2) << "Calling SyncShare with " | 749 SDVLOG(2) << "Calling SyncShare with " |
| 753 << SyncSessionJob::GetPurposeString(job->purpose()) << " job"; | 750 << SyncSessionJob::GetPurposeString(job->purpose()) << " job"; |
| 754 bool premature_exit = !syncer_->SyncShare(job->mutable_session(), | 751 bool premature_exit = !syncer_->SyncShare(job->mutable_session(), |
| 755 job->start_step(), | 752 job->start_step(), |
| 756 job->end_step()); | 753 job->end_step()); |
| 757 SDVLOG(2) << "Done SyncShare, returned: " << premature_exit; | 754 SDVLOG(2) << "Done SyncShare, returned: " << premature_exit; |
| 758 | 755 |
| 759 return FinishSyncSessionJob(job.Pass(), premature_exit); | 756 bool success = FinishSyncSessionJob(job.get(), premature_exit); |
| 757 | |
| 758 if (IsSyncingCurrentlySilenced()) { | |
| 759 SDVLOG(2) << "We are currently throttled; scheduling Unthrottle."; | |
| 760 // If we're here, it's because |job| was silenced until a server specified | |
| 761 // time. (Note, it had to be |job|, because DecideOnJob would not permit | |
| 762 // any job through while in WaitInterval::THROTTLED). | |
| 763 scoped_ptr<SyncSessionJob> clone = job->Clone(); | |
| 764 if (clone->purpose() == SyncSessionJob::NUDGE) | |
| 765 pending_nudge_ = clone.get(); | |
| 766 else if (clone->purpose() == SyncSessionJob::CONFIGURATION) | |
| 767 wait_interval_->pending_configure_job = clone.get(); | |
| 768 else | |
| 769 NOTREACHED(); | |
| 770 | |
| 771 RestartWaiting(clone.Pass()); | |
| 772 return success; | |
| 773 } | |
| 774 | |
| 775 if (!success) | |
| 776 ScheduleNextSync(job.Pass()); | |
| 777 | |
| 778 return success; | |
| 779 } | |
| 780 | |
| 781 bool SyncSchedulerImpl::DecideOnPollJob() { | |
| 782 if (wait_interval_.get()) { | |
| 783 SDVLOG(2) << "Dropping POLL job in wait interval."; | |
| 784 return false; | |
| 785 } | |
| 786 | |
| 787 if (mode_ == CONFIGURATION_MODE) { | |
| 788 SDVLOG(2) << "Dropping POLL job in configuration mode."; | |
| 789 return false; | |
| 790 } | |
| 791 | |
| 792 if (session_context_->connection_manager()->HasInvalidAuthToken()) { | |
|
tim (not reviewing)
2013/03/19 21:50:02
Can you add a TODO to track moving this to a DoCom
rlarocque
2013/03/19 22:46:42
Done.
| |
| 793 SDVLOG(2) << "Dropping POLL job because auth token is invalid."; | |
| 794 return false; | |
| 795 } | |
| 796 | |
| 797 return true; | |
| 798 } | |
| 799 | |
| 800 void SyncSchedulerImpl::DoPollSyncSessionJob(scoped_ptr<SyncSessionJob> job) { | |
| 801 DCHECK_EQ(job->purpose(), SyncSessionJob::POLL); | |
| 802 | |
| 803 base::AutoReset<bool> protector(&no_scheduling_allowed_, true); | |
| 804 | |
| 805 if (!DecideOnPollJob()) | |
|
tim (not reviewing)
2013/03/19 21:50:02
Is your plant o make DecideOnJob() return a bool a
rlarocque
2013/03/19 22:46:42
You're right. This CL is probably the most approp
rlarocque
2013/03/19 22:46:42
You're right that the name should change. I think
| |
| 806 return; | |
| 807 | |
| 808 SDVLOG(2) << "Calling SyncShare with " | |
| 809 << SyncSessionJob::GetPurposeString(job->purpose()) << " job"; | |
| 810 bool premature_exit = !syncer_->SyncShare(job->mutable_session(), | |
| 811 job->start_step(), | |
| 812 job->end_step()); | |
| 813 SDVLOG(2) << "Done SyncShare, returned: " << premature_exit; | |
| 814 | |
| 815 FinishSyncSessionJob(job.get(), premature_exit); | |
| 816 | |
| 817 if (IsSyncingCurrentlySilenced()) { | |
| 818 // This will start the countdown to unthrottle. Other kinds of jobs would | |
| 819 // schedule themselves as the post-unthrottle canary. A poll job is not | |
| 820 // that urgent, so it does not get to be the canary. We still need to start | |
| 821 // the timer regardless. Otherwise there could be no one to clear the | |
| 822 // WaitInterval when the throttling expires. | |
| 823 RestartWaiting(scoped_ptr<SyncSessionJob>()); | |
| 824 } | |
| 760 } | 825 } |
| 761 | 826 |
| 762 void SyncSchedulerImpl::UpdateNudgeTimeRecords(const SyncSourceInfo& info) { | 827 void SyncSchedulerImpl::UpdateNudgeTimeRecords(const SyncSourceInfo& info) { |
| 763 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 828 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 764 | 829 |
| 765 // We are interested in recording time between local nudges for datatypes. | 830 // We are interested in recording time between local nudges for datatypes. |
| 766 // TODO(tim): Consider tracking LOCAL_NOTIFICATION as well. | 831 // TODO(tim): Consider tracking LOCAL_NOTIFICATION as well. |
| 767 if (info.updates_source != GetUpdatesCallerInfo::LOCAL) | 832 if (info.updates_source != GetUpdatesCallerInfo::LOCAL) |
| 768 return; | 833 return; |
| 769 | 834 |
| 770 base::TimeTicks now = TimeTicks::Now(); | 835 base::TimeTicks now = TimeTicks::Now(); |
| 771 // Update timing information for how often datatypes are triggering nudges. | 836 // Update timing information for how often datatypes are triggering nudges. |
| 772 for (ModelTypeInvalidationMap::const_iterator iter = info.types.begin(); | 837 for (ModelTypeInvalidationMap::const_iterator iter = info.types.begin(); |
| 773 iter != info.types.end(); | 838 iter != info.types.end(); |
| 774 ++iter) { | 839 ++iter) { |
| 775 base::TimeTicks previous = last_local_nudges_by_model_type_[iter->first]; | 840 base::TimeTicks previous = last_local_nudges_by_model_type_[iter->first]; |
| 776 last_local_nudges_by_model_type_[iter->first] = now; | 841 last_local_nudges_by_model_type_[iter->first] = now; |
| 777 if (previous.is_null()) | 842 if (previous.is_null()) |
| 778 continue; | 843 continue; |
| 779 | 844 |
| 780 #define PER_DATA_TYPE_MACRO(type_str) \ | 845 #define PER_DATA_TYPE_MACRO(type_str) \ |
| 781 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); | 846 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); |
| 782 SYNC_DATA_TYPE_HISTOGRAM(iter->first); | 847 SYNC_DATA_TYPE_HISTOGRAM(iter->first); |
| 783 #undef PER_DATA_TYPE_MACRO | 848 #undef PER_DATA_TYPE_MACRO |
| 784 } | 849 } |
| 785 } | 850 } |
| 786 | 851 |
| 787 bool SyncSchedulerImpl::FinishSyncSessionJob(scoped_ptr<SyncSessionJob> job, | 852 bool SyncSchedulerImpl::FinishSyncSessionJob(SyncSessionJob* job, |
| 788 bool exited_prematurely) { | 853 bool exited_prematurely) { |
| 789 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 854 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 790 | 855 |
| 791 // Let job know that we're through syncing (calling SyncShare) at this point. | 856 // Let job know that we're through syncing (calling SyncShare) at this point. |
| 792 bool succeeded = false; | 857 bool succeeded = false; |
| 793 { | 858 { |
| 794 base::AutoReset<bool> protector(&no_scheduling_allowed_, true); | 859 base::AutoReset<bool> protector(&no_scheduling_allowed_, true); |
| 795 succeeded = job->Finish(exited_prematurely); | 860 succeeded = job->Finish(exited_prematurely); |
| 796 } | 861 } |
| 797 | 862 |
| 798 SDVLOG(2) << "Updating the next polling time after SyncMain"; | 863 SDVLOG(2) << "Updating the next polling time after SyncMain"; |
| 799 ScheduleNextSync(job.Pass(), succeeded); | |
| 800 return succeeded; | |
| 801 } | |
| 802 | 864 |
| 803 void SyncSchedulerImpl::ScheduleNextSync( | 865 AdjustPolling(job); |
| 804 scoped_ptr<SyncSessionJob> finished_job, bool succeeded) { | |
| 805 DCHECK_EQ(MessageLoop::current(), sync_loop_); | |
| 806 | |
| 807 AdjustPolling(finished_job.get()); | |
| 808 | 866 |
| 809 if (succeeded) { | 867 if (succeeded) { |
| 810 // No job currently supported by the scheduler could succeed without | 868 // No job currently supported by the scheduler could succeed without |
| 811 // successfully reaching the server. Therefore, if we make it here, it is | 869 // successfully reaching the server. Therefore, if we make it here, it is |
| 812 // appropriate to reset the backoff interval. | 870 // appropriate to reset the backoff interval. |
| 813 wait_interval_.reset(); | 871 wait_interval_.reset(); |
| 814 NotifyRetryTime(base::Time()); | 872 NotifyRetryTime(base::Time()); |
| 815 SDVLOG(2) << "Job succeeded so not scheduling more jobs"; | 873 SDVLOG(2) << "Job succeeded so not scheduling more jobs"; |
| 816 return; | |
| 817 } | 874 } |
| 818 | 875 |
| 819 if (IsSyncingCurrentlySilenced()) { | 876 return succeeded; |
| 820 SDVLOG(2) << "We are currently throttled; scheduling Unthrottle."; | 877 } |
| 821 // If we're here, it's because |job| was silenced until a server specified | |
| 822 // time. (Note, it had to be |job|, because DecideOnJob would not permit | |
| 823 // any job through while in WaitInterval::THROTTLED). | |
| 824 scoped_ptr<SyncSessionJob> clone = finished_job->Clone(); | |
| 825 if (clone->purpose() == SyncSessionJob::NUDGE) | |
| 826 pending_nudge_ = clone.get(); | |
| 827 else if (clone->purpose() == SyncSessionJob::CONFIGURATION) | |
| 828 wait_interval_->pending_configure_job = clone.get(); | |
| 829 else | |
| 830 clone.reset(); // Unthrottling is enough, no need to force a canary. | |
| 831 | 878 |
| 832 RestartWaiting(clone.Pass()); | 879 void SyncSchedulerImpl::ScheduleNextSync( |
| 833 return; | 880 scoped_ptr<SyncSessionJob> finished_job) { |
| 834 } | 881 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 835 | 882 DCHECK(finished_job->purpose() == SyncSessionJob::CONFIGURATION |
| 836 if (finished_job->purpose() == SyncSessionJob::POLL) { | 883 || finished_job->purpose() == SyncSessionJob::NUDGE); |
| 837 return; // We don't retry POLL jobs. | |
| 838 } | |
| 839 | 884 |
| 840 // TODO(rlarocque): There's no reason why we should blindly backoff and retry | 885 // TODO(rlarocque): There's no reason why we should blindly backoff and retry |
| 841 // if we don't succeed. Some types of errors are not likely to disappear on | 886 // if we don't succeed. Some types of errors are not likely to disappear on |
| 842 // their own. With the return values now available in the old_job.session, | 887 // their own. With the return values now available in the old_job.session, |
| 843 // we should be able to detect such errors and only retry when we detect | 888 // we should be able to detect such errors and only retry when we detect |
| 844 // transient errors. | 889 // transient errors. |
| 845 | 890 |
| 846 if (IsBackingOff() && wait_interval_->timer.IsRunning() && | 891 if (IsBackingOff() && wait_interval_->timer.IsRunning() && |
| 847 mode_ == NORMAL_MODE) { | 892 mode_ == NORMAL_MODE) { |
| 848 // When in normal mode, we allow up to one nudge per backoff interval. It | 893 // When in normal mode, we allow up to one nudge per backoff interval. It |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 973 void SyncSchedulerImpl::DoCanaryJob(scoped_ptr<SyncSessionJob> to_be_canary) { | 1018 void SyncSchedulerImpl::DoCanaryJob(scoped_ptr<SyncSessionJob> to_be_canary) { |
| 974 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1019 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 975 SDVLOG(2) << "Do canary job"; | 1020 SDVLOG(2) << "Do canary job"; |
| 976 | 1021 |
| 977 if (to_be_canary->purpose() == SyncSessionJob::NUDGE) { | 1022 if (to_be_canary->purpose() == SyncSessionJob::NUDGE) { |
| 978 // TODO(tim): Bug 158313. Remove this check. | 1023 // TODO(tim): Bug 158313. Remove this check. |
| 979 if (pending_nudge_ == NULL || | 1024 if (pending_nudge_ == NULL || |
| 980 pending_nudge_->session() != to_be_canary->session()) { | 1025 pending_nudge_->session() != to_be_canary->session()) { |
| 981 // |job| is abandoned. | 1026 // |job| is abandoned. |
| 982 SDVLOG(2) << "Dropping a nudge in " | 1027 SDVLOG(2) << "Dropping a nudge in " |
| 983 << "DoSyncSessionJob because another nudge was scheduled"; | 1028 << "DoCanaryJob because another nudge was scheduled"; |
| 984 return; | 1029 return; |
| 985 } | 1030 } |
| 986 DCHECK_EQ(pending_nudge_->session(), to_be_canary->session()); | 1031 DCHECK_EQ(pending_nudge_->session(), to_be_canary->session()); |
| 987 } | 1032 } |
| 988 | 1033 |
| 989 // This is the only place where we invoke DoSyncSessionJob with canary | 1034 // This is the only place where we invoke DoSyncSessionJob with canary |
| 990 // privileges. Everyone else should use NORMAL_PRIORITY. | 1035 // privileges. Everyone else should use NORMAL_PRIORITY. |
| 991 DoSyncSessionJob(to_be_canary.Pass(), CANARY_PRIORITY); | 1036 DoSyncSessionJob(to_be_canary.Pass(), CANARY_PRIORITY); |
| 992 } | 1037 } |
| 993 | 1038 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1028 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1073 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1029 ModelSafeRoutingInfo r; | 1074 ModelSafeRoutingInfo r; |
| 1030 ModelTypeInvalidationMap invalidation_map = | 1075 ModelTypeInvalidationMap invalidation_map = |
| 1031 ModelSafeRoutingInfoToInvalidationMap(r, std::string()); | 1076 ModelSafeRoutingInfoToInvalidationMap(r, std::string()); |
| 1032 SyncSourceInfo info(GetUpdatesCallerInfo::PERIODIC, invalidation_map); | 1077 SyncSourceInfo info(GetUpdatesCallerInfo::PERIODIC, invalidation_map); |
| 1033 scoped_ptr<SyncSession> s(CreateSyncSession(info)); | 1078 scoped_ptr<SyncSession> s(CreateSyncSession(info)); |
| 1034 scoped_ptr<SyncSessionJob> job(new SyncSessionJob(SyncSessionJob::POLL, | 1079 scoped_ptr<SyncSessionJob> job(new SyncSessionJob(SyncSessionJob::POLL, |
| 1035 TimeTicks::Now(), | 1080 TimeTicks::Now(), |
| 1036 s.Pass(), | 1081 s.Pass(), |
| 1037 ConfigurationParams())); | 1082 ConfigurationParams())); |
| 1038 ScheduleSyncSessionJob(FROM_HERE, job.Pass()); | 1083 if (no_scheduling_allowed_) { |
| 1084 // The no_scheduling_allowed_ flag is set by a function-scoped AutoReset in | |
| 1085 // functions that are called only on the sync thread. This function is also | |
| 1086 // called only on the sync thread, and only when it is posted by an expiring | |
| 1087 // timer. If we find that no_scheduling_allowed_ is set here, then | |
| 1088 // something is very wrong. Maybe someone mistakenly called us directly, or | |
| 1089 // mishandled the book-keeping for no_scheduling_allowed_. | |
| 1090 NOTREACHED() << "Illegal to schedule job while session in progress."; | |
| 1091 return; | |
| 1092 } | |
| 1093 | |
| 1094 DoPollSyncSessionJob(job.Pass()); | |
| 1039 } | 1095 } |
| 1040 | 1096 |
| 1041 void SyncSchedulerImpl::Unthrottle(scoped_ptr<SyncSessionJob> to_be_canary) { | 1097 void SyncSchedulerImpl::Unthrottle(scoped_ptr<SyncSessionJob> to_be_canary) { |
| 1042 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1098 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1043 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode); | 1099 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode); |
| 1044 DCHECK(!to_be_canary.get() || pending_nudge_ == to_be_canary.get() || | 1100 DCHECK(!to_be_canary.get() || pending_nudge_ == to_be_canary.get() || |
| 1045 wait_interval_->pending_configure_job == to_be_canary.get()); | 1101 wait_interval_->pending_configure_job == to_be_canary.get()); |
| 1046 SDVLOG(2) << "Unthrottled " << (to_be_canary.get() ? "with " : "without ") | 1102 SDVLOG(2) << "Unthrottled " << (to_be_canary.get() ? "with " : "without ") |
| 1047 << "canary."; | 1103 << "canary."; |
| 1048 | 1104 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1151 | 1207 |
| 1152 #undef SDVLOG_LOC | 1208 #undef SDVLOG_LOC |
| 1153 | 1209 |
| 1154 #undef SDVLOG | 1210 #undef SDVLOG |
| 1155 | 1211 |
| 1156 #undef SLOG | 1212 #undef SLOG |
| 1157 | 1213 |
| 1158 #undef ENUM_CASE | 1214 #undef ENUM_CASE |
| 1159 | 1215 |
| 1160 } // namespace syncer | 1216 } // namespace syncer |
| OLD | NEW |