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

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

Issue 2828423002: [Sync] Sync types never recovers from throttle (Closed)
Patch Set: fix Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | components/sync/engine_impl/sync_scheduler_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 603 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « no previous file | components/sync/engine_impl/sync_scheduler_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698