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 "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 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 614 SDVLOG(1) << "Updating polling delay to " << poll_delay.InMinutes() | 614 SDVLOG(1) << "Updating polling delay to " << poll_delay.InMinutes() |
| 615 << " minutes."; | 615 << " minutes."; |
| 616 | 616 |
| 617 // Adjust poll rate. Start will reset the timer if it was already running. | 617 // Adjust poll rate. Start will reset the timer if it was already running. |
| 618 poll_timer_.Start(FROM_HERE, poll_delay, this, | 618 poll_timer_.Start(FROM_HERE, poll_delay, this, |
| 619 &SyncSchedulerImpl::PollTimerCallback); | 619 &SyncSchedulerImpl::PollTimerCallback); |
| 620 } | 620 } |
| 621 | 621 |
| 622 void SyncSchedulerImpl::RestartWaiting() { | 622 void SyncSchedulerImpl::RestartWaiting() { |
| 623 if (wait_interval_.get()) { | 623 if (wait_interval_.get()) { |
| 624 // Global throttling or backoff | 624 // Global throttling or backoff |
|
skym
2017/04/21 16:06:34
Can you add a comment explaining why you overwrite
Gang Wu
2017/04/25 00:52:05
Done.
| |
| 625 NotifyRetryTime(base::Time::Now() + wait_interval_->length); | 625 NotifyRetryTime(base::Time::Now() + wait_interval_->length); |
| 626 SDVLOG(2) << "Starting WaitInterval timer of length " | 626 SDVLOG(2) << "Starting WaitInterval timer of length " |
| 627 << wait_interval_->length.InMilliseconds() << "ms."; | 627 << wait_interval_->length.InMilliseconds() << "ms."; |
| 628 if (wait_interval_->mode == WaitInterval::THROTTLED) { | 628 if (wait_interval_->mode == WaitInterval::THROTTLED) { |
| 629 pending_wakeup_timer_.Start(FROM_HERE, wait_interval_->length, | 629 pending_wakeup_timer_.Start(FROM_HERE, wait_interval_->length, |
| 630 base::Bind(&SyncSchedulerImpl::Unthrottle, | 630 base::Bind(&SyncSchedulerImpl::Unthrottle, |
| 631 weak_ptr_factory_.GetWeakPtr())); | 631 weak_ptr_factory_.GetWeakPtr())); |
| 632 } else { | 632 } else { |
| 633 pending_wakeup_timer_.Start( | 633 pending_wakeup_timer_.Start( |
| 634 FROM_HERE, wait_interval_->length, | 634 FROM_HERE, wait_interval_->length, |
| 635 base::Bind(&SyncSchedulerImpl::ExponentialBackoffRetry, | 635 base::Bind(&SyncSchedulerImpl::ExponentialBackoffRetry, |
| 636 weak_ptr_factory_.GetWeakPtr())); | 636 weak_ptr_factory_.GetWeakPtr())); |
| 637 } | 637 } |
| 638 } else if (nudge_tracker_.IsAnyTypeBlocked()) { | 638 } else if (nudge_tracker_.IsAnyTypeBlocked()) { |
| 639 // Per-datatype throttled or backed off. | 639 // Per-datatype throttled or backed off. |
| 640 TimeDelta time_until_next_unblock = | 640 TimeDelta time_until_next_unblock = |
| 641 nudge_tracker_.GetTimeUntilNextUnblock(); | 641 nudge_tracker_.GetTimeUntilNextUnblock(); |
| 642 TimeTicks incoming_run_time = TimeTicks::Now() + time_until_next_unblock; | |
|
skym
2017/04/21 16:06:34
I think this logic already exists in this file, ma
Gang Wu
2017/04/25 00:52:05
Done.
| |
| 643 if (pending_wakeup_timer_.IsRunning() && | |
| 644 (pending_wakeup_timer_.desired_run_time() < incoming_run_time)) { | |
| 645 // Old job arrives sooner than this one. Don't reschedule it. | |
| 646 return; | |
| 647 } | |
| 642 pending_wakeup_timer_.Start(FROM_HERE, time_until_next_unblock, | 648 pending_wakeup_timer_.Start(FROM_HERE, time_until_next_unblock, |
| 643 base::Bind(&SyncSchedulerImpl::OnTypesUnblocked, | 649 base::Bind(&SyncSchedulerImpl::OnTypesUnblocked, |
| 644 weak_ptr_factory_.GetWeakPtr())); | 650 weak_ptr_factory_.GetWeakPtr())); |
| 645 } | 651 } |
| 646 } | 652 } |
| 647 | 653 |
| 648 void SyncSchedulerImpl::Stop() { | 654 void SyncSchedulerImpl::Stop() { |
| 649 DCHECK(CalledOnValidThread()); | 655 DCHECK(CalledOnValidThread()); |
| 650 SDVLOG(2) << "Stop called"; | 656 SDVLOG(2) << "Stop called"; |
| 651 | 657 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 726 CHECK(!syncer_->IsSyncing()); | 732 CHECK(!syncer_->IsSyncing()); |
| 727 | 733 |
| 728 TrySyncCycleJob(); | 734 TrySyncCycleJob(); |
| 729 } | 735 } |
| 730 | 736 |
| 731 void SyncSchedulerImpl::RetryTimerCallback() { | 737 void SyncSchedulerImpl::RetryTimerCallback() { |
| 732 TrySyncCycleJob(); | 738 TrySyncCycleJob(); |
| 733 } | 739 } |
| 734 | 740 |
| 735 void SyncSchedulerImpl::Unthrottle() { | 741 void SyncSchedulerImpl::Unthrottle() { |
| 736 DCHECK(CalledOnValidThread()); | 742 DCHECK(CalledOnValidThread()); |
|
skym
2017/04/21 16:06:34
Can you audit these CalledOnValidThread()? I think
Gang Wu
2017/04/25 00:52:05
Done.
| |
| 737 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode); | 743 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode); |
| 738 | 744 |
| 739 // We're no longer throttled, so clear the wait interval. | 745 // We're no longer throttled, so clear the wait interval. |
| 740 wait_interval_.reset(); | 746 wait_interval_.reset(); |
| 741 NotifyRetryTime(base::Time()); | 747 NotifyRetryTime(base::Time()); |
| 742 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); | 748 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); |
| 743 | 749 |
| 750 // There may have some datatypes are in backoff or throttled before this | |
| 751 // global throttling, so rechedule for them. | |
| 752 RestartWaiting(); | |
|
skym
2017/04/21 16:06:34
Sprinkling RestartWaiting()s all over the place, a
Gang Wu
2017/04/25 00:52:05
Done.
| |
| 753 | |
| 744 // We treat this as a 'canary' in the sense that it was originally scheduled | 754 // We treat this as a 'canary' in the sense that it was originally scheduled |
| 745 // to run some time ago, failed, and we now want to retry, versus a job that | 755 // to run some time ago, failed, and we now want to retry, versus a job that |
| 746 // was just created (e.g via ScheduleNudgeImpl). The main implication is | 756 // was just created (e.g via ScheduleNudgeImpl). The main implication is |
| 747 // that we're careful to update routing info (etc) with such potentially | 757 // that we're careful to update routing info (etc) with such potentially |
| 748 // stale canary jobs. | 758 // stale canary jobs. |
| 749 TryCanaryJob(); | 759 TryCanaryJob(); |
| 750 } | 760 } |
| 751 | 761 |
| 752 void SyncSchedulerImpl::OnTypesUnblocked() { | 762 void SyncSchedulerImpl::OnTypesUnblocked() { |
| 753 DCHECK(CalledOnValidThread()); | 763 DCHECK(CalledOnValidThread()); |
| 754 nudge_tracker_.UpdateTypeThrottlingAndBackoffState(); | 764 nudge_tracker_.UpdateTypeThrottlingAndBackoffState(); |
|
skym
2017/04/21 16:06:34
This function makes no sense to me. I am unable to
Gang Wu
2017/04/25 00:52:05
Each datatype may have different backoff time, for
skym
2017/04/25 23:16:17
Yes, but |unblock_time_| is inside of DataTypeTrac
Gang Wu
2017/04/29 15:06:16
You mean something like BOOKMARK got in throttling
skym
2017/05/01 17:59:14
No, I'm saying that the code checks |unblock_time_
Gang Wu
2017/05/01 23:01:40
oh, I see. we cannot clear for backoff case since
| |
| 755 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); | 765 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); |
| 756 | 766 |
| 757 RestartWaiting(); | 767 RestartWaiting(); |
|
skym
2017/04/21 16:06:34
Why isn't RestartWaiting() the last thing done in
Gang Wu
2017/04/25 00:52:06
Done.
| |
| 758 | 768 |
| 759 // Maybe this is a good time to run a nudge job. Let's try it. | 769 // Maybe this is a good time to run a nudge job. Let's try it. |
| 760 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) | 770 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) |
| 761 TrySyncCycleJob(); | 771 TrySyncCycleJob(); |
| 762 } | 772 } |
| 763 | 773 |
| 764 void SyncSchedulerImpl::PerformDelayedNudge() { | 774 void SyncSchedulerImpl::PerformDelayedNudge() { |
| 765 // Circumstances may have changed since we scheduled this delayed nudge. | 775 // Circumstances may have changed since we scheduled this delayed nudge. |
| 766 // We must check to see if it's OK to run the job before we do so. | 776 // We must check to see if it's OK to run the job before we do so. |
| 767 if (CanRunNudgeJobNow(NORMAL_PRIORITY)) | 777 if (CanRunNudgeJobNow(NORMAL_PRIORITY)) |
| 768 TrySyncCycleJob(); | 778 TrySyncCycleJob(); |
| 769 | 779 |
| 770 // We're not responsible for setting up any retries here. The functions that | 780 // Since PerformDelayedNudge share pending_wakeup_timer_ with |
| 771 // first put us into a state that prevents successful sync cycles (eg. global | 781 // OnTypesUnblocked, Unthrottle and ExponentialBackoffRetry, we should check |
| 772 // throttling, type throttling, network errors, transient errors) will also | 782 // if there are any of those functions needed to be scheduled. |
| 773 // setup the appropriate retry logic (eg. retry after timeout, exponential | 783 RestartWaiting(); |
|
skym
2017/04/21 16:06:34
Why isn't RestartWaiting() the last thing done in
Gang Wu
2017/04/25 00:52:05
Where to run RestartWaiting() is not a matter, we
| |
| 774 // backoff, retry when the network changes). | |
| 775 } | 784 } |
| 776 | 785 |
| 777 void SyncSchedulerImpl::ExponentialBackoffRetry() { | 786 void SyncSchedulerImpl::ExponentialBackoffRetry() { |
| 778 TryCanaryJob(); | 787 TryCanaryJob(); |
| 788 | |
| 789 if (!IsBackingOff()) { | |
| 790 // There may have some datatypes are in backoff or throttled before this | |
| 791 // global backoff, so rechedule for them. | |
| 792 RestartWaiting(); | |
| 793 } | |
| 779 } | 794 } |
| 780 | 795 |
| 781 void SyncSchedulerImpl::NotifyRetryTime(base::Time retry_time) { | 796 void SyncSchedulerImpl::NotifyRetryTime(base::Time retry_time) { |
| 782 for (auto& observer : *cycle_context_->listeners()) | 797 for (auto& observer : *cycle_context_->listeners()) |
| 783 observer.OnRetryTimeChanged(retry_time); | 798 observer.OnRetryTimeChanged(retry_time); |
| 784 } | 799 } |
| 785 | 800 |
| 786 void SyncSchedulerImpl::NotifyBlockedTypesChanged(ModelTypeSet types) { | 801 void SyncSchedulerImpl::NotifyBlockedTypesChanged(ModelTypeSet types) { |
| 787 ModelTypeSet throttled_types; | 802 ModelTypeSet throttled_types; |
| 788 ModelTypeSet backed_off_types; | 803 ModelTypeSet backed_off_types; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 902 } | 917 } |
| 903 if (IsActionableError(sync_protocol_error)) { | 918 if (IsActionableError(sync_protocol_error)) { |
| 904 SDVLOG(2) << "OnActionableError"; | 919 SDVLOG(2) << "OnActionableError"; |
| 905 for (auto& observer : *cycle_context_->listeners()) | 920 for (auto& observer : *cycle_context_->listeners()) |
| 906 observer.OnActionableError(sync_protocol_error); | 921 observer.OnActionableError(sync_protocol_error); |
| 907 } | 922 } |
| 908 } | 923 } |
| 909 | 924 |
| 910 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const TimeDelta& delay) { | 925 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const TimeDelta& delay) { |
| 911 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + delay); | 926 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + delay); |
| 912 retry_timer_.Start(FROM_HERE, delay, this, | 927 retry_timer_.Start(FROM_HERE, delay, this, |
|
skym
2017/04/21 16:06:34
Why do we have a separate timer for this? Why is t
Gang Wu
2017/04/25 00:52:05
There are a lot of logic here.
poll_timer_ is for
| |
| 913 &SyncSchedulerImpl::RetryTimerCallback); | 928 &SyncSchedulerImpl::RetryTimerCallback); |
| 914 } | 929 } |
| 915 | 930 |
| 916 void SyncSchedulerImpl::OnReceivedMigrationRequest(ModelTypeSet types) { | 931 void SyncSchedulerImpl::OnReceivedMigrationRequest(ModelTypeSet types) { |
| 917 for (auto& observer : *cycle_context_->listeners()) | 932 for (auto& observer : *cycle_context_->listeners()) |
| 918 observer.OnMigrationRequested(types); | 933 observer.OnMigrationRequested(types); |
| 919 } | 934 } |
| 920 | 935 |
| 921 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { | 936 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { |
| 922 DCHECK(CalledOnValidThread()); | 937 DCHECK(CalledOnValidThread()); |
| 923 cycle_context_->set_notifications_enabled(notifications_enabled); | 938 cycle_context_->set_notifications_enabled(notifications_enabled); |
| 924 if (notifications_enabled) | 939 if (notifications_enabled) |
| 925 nudge_tracker_.OnInvalidationsEnabled(); | 940 nudge_tracker_.OnInvalidationsEnabled(); |
| 926 else | 941 else |
| 927 nudge_tracker_.OnInvalidationsDisabled(); | 942 nudge_tracker_.OnInvalidationsDisabled(); |
| 928 } | 943 } |
| 929 | 944 |
| 930 #undef SDVLOG_LOC | 945 #undef SDVLOG_LOC |
| 931 | 946 |
| 932 #undef SDVLOG | 947 #undef SDVLOG |
| 933 | 948 |
| 934 #undef SLOG | 949 #undef SLOG |
| 935 | 950 |
| 936 #undef ENUM_CASE | 951 #undef ENUM_CASE |
| 937 | 952 |
| 938 } // namespace syncer | 953 } // namespace syncer |
| OLD | NEW |