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 |