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

Side by Side Diff: sync/engine/sync_scheduler_impl.cc

Issue 124083002: Client-side changes to support retry GU. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 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 | Annotate | Revision Log
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 "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"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
17 #include "base/time/default_clock.h"
17 #include "sync/engine/backoff_delay_provider.h" 18 #include "sync/engine/backoff_delay_provider.h"
18 #include "sync/engine/syncer.h" 19 #include "sync/engine/syncer.h"
19 #include "sync/notifier/object_id_invalidation_map.h" 20 #include "sync/notifier/object_id_invalidation_map.h"
20 #include "sync/protocol/proto_enum_conversions.h" 21 #include "sync/protocol/proto_enum_conversions.h"
21 #include "sync/protocol/sync.pb.h" 22 #include "sync/protocol/sync.pb.h"
22 #include "sync/util/data_type_histogram.h" 23 #include "sync/util/data_type_histogram.h"
23 #include "sync/util/logging.h" 24 #include "sync/util/logging.h"
24 25
25 using base::TimeDelta; 26 using base::TimeDelta;
26 using base::TimeTicks; 27 using base::TimeTicks;
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 } 228 }
228 229
229 DCHECK(!session_context_->account_name().empty()); 230 DCHECK(!session_context_->account_name().empty());
230 DCHECK(syncer_.get()); 231 DCHECK(syncer_.get());
231 Mode old_mode = mode_; 232 Mode old_mode = mode_;
232 mode_ = mode; 233 mode_ = mode;
233 AdjustPolling(UPDATE_INTERVAL); // Will kick start poll timer if needed. 234 AdjustPolling(UPDATE_INTERVAL); // Will kick start poll timer if needed.
234 235
235 if (old_mode != mode_ && 236 if (old_mode != mode_ &&
236 mode_ == NORMAL_MODE && 237 mode_ == NORMAL_MODE &&
237 nudge_tracker_.IsSyncRequired() && 238 (nudge_tracker_.IsSyncRequired() ||
239 nudge_tracker_.IsRetryRequired(base::TimeTicks::Now())) &&
238 CanRunNudgeJobNow(NORMAL_PRIORITY)) { 240 CanRunNudgeJobNow(NORMAL_PRIORITY)) {
239 // 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
240 // queued up while we were configuring. 242 // queued up while we were configuring.
241 TrySyncSessionJob(); 243 TrySyncSessionJob();
242 } 244 }
243 } 245 }
244 246
245 ModelTypeSet SyncSchedulerImpl::GetEnabledAndUnthrottledTypes() { 247 ModelTypeSet SyncSchedulerImpl::GetEnabledAndUnthrottledTypes() {
246 ModelTypeSet enabled_types = session_context_->enabled_types(); 248 ModelTypeSet enabled_types = session_context_->enabled_types();
247 ModelTypeSet throttled_types = nudge_tracker_.GetThrottledTypes(); 249 ModelTypeSet throttled_types = nudge_tracker_.GetThrottledTypes();
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 // Don't run poll job till the next time poll timer fires. 464 // Don't run poll job till the next time poll timer fires.
463 do_poll_after_credentials_updated_ = false; 465 do_poll_after_credentials_updated_ = false;
464 466
465 bool success = !premature_exit 467 bool success = !premature_exit
466 && !sessions::HasSyncerError( 468 && !sessions::HasSyncerError(
467 session->status_controller().model_neutral_state()); 469 session->status_controller().model_neutral_state());
468 470
469 if (success) { 471 if (success) {
470 // That cycle took care of any outstanding work we had. 472 // That cycle took care of any outstanding work we had.
471 SDVLOG(2) << "Nudge succeeded."; 473 SDVLOG(2) << "Nudge succeeded.";
472 nudge_tracker_.RecordSuccessfulSyncCycle(); 474 nudge_tracker_.RecordSuccessfulSyncCycle(base::TimeTicks::Now());
473 scheduled_nudge_time_ = base::TimeTicks(); 475 scheduled_nudge_time_ = base::TimeTicks();
474 476
475 // If we're here, then we successfully reached the server. End all backoff. 477 // If we're here, then we successfully reached the server. End all backoff.
476 wait_interval_.reset(); 478 wait_interval_.reset();
477 NotifyRetryTime(base::Time()); 479 NotifyRetryTime(base::Time());
478 return; 480 return;
479 } else { 481 } else {
480 HandleFailure(session->status_controller().model_neutral_state()); 482 HandleFailure(session->status_controller().model_neutral_state());
481 } 483 }
482 } 484 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, length)); 544 new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, length));
543 SDVLOG(2) << "Sync cycle failed. Will back off for " 545 SDVLOG(2) << "Sync cycle failed. Will back off for "
544 << wait_interval_->length.InMilliseconds() << "ms."; 546 << wait_interval_->length.InMilliseconds() << "ms.";
545 RestartWaiting(); 547 RestartWaiting();
546 } 548 }
547 } 549 }
548 550
549 void SyncSchedulerImpl::DoPollSyncSessionJob() { 551 void SyncSchedulerImpl::DoPollSyncSessionJob() {
550 base::AutoReset<bool> protector(&no_scheduling_allowed_, true); 552 base::AutoReset<bool> protector(&no_scheduling_allowed_, true);
551 553
552 if (!CanRunJobNow(NORMAL_PRIORITY)) {
553 SDVLOG(2) << "Unable to run a poll job right now.";
554 return;
555 }
556
557 if (mode_ != NORMAL_MODE) {
558 SDVLOG(2) << "Not running poll job in configure mode.";
559 return;
560 }
561
562 SDVLOG(2) << "Polling with types " 554 SDVLOG(2) << "Polling with types "
563 << ModelTypeSetToString(session_context_->enabled_types()); 555 << ModelTypeSetToString(GetEnabledAndUnthrottledTypes());
564 scoped_ptr<SyncSession> session(SyncSession::Build(session_context_, this)); 556 scoped_ptr<SyncSession> session(SyncSession::Build(session_context_, this));
565 syncer_->PollSyncShare( 557 syncer_->PollSyncShare(
566 GetEnabledAndUnthrottledTypes(), 558 GetEnabledAndUnthrottledTypes(),
567 session.get()); 559 session.get());
568 560
569 AdjustPolling(FORCE_RESET); 561 AdjustPolling(FORCE_RESET);
570 562
571 if (IsCurrentlyThrottled()) { 563 if (IsCurrentlyThrottled()) {
572 SDVLOG(2) << "Poll request got us throttled."; 564 SDVLOG(2) << "Poll request got us throttled.";
573 // The OnSilencedUntil() call set up the WaitInterval for us. All we need 565 // The OnSilencedUntil() call set up the WaitInterval for us. All we need
574 // to do is start the timer. 566 // to do is start the timer.
575 RestartWaiting(); 567 RestartWaiting();
576 } 568 }
577 } 569 }
578 570
571 void SyncSchedulerImpl::DoRetrySyncSessionJob() {
572 DCHECK(CalledOnValidThread());
573 DCHECK_EQ(mode_, NORMAL_MODE);
574
575 base::AutoReset<bool> protector(&no_scheduling_allowed_, true);
576
577 SDVLOG(2) << "Retrying with types "
578 << ModelTypeSetToString(GetEnabledAndUnthrottledTypes());
579 scoped_ptr<SyncSession> session(SyncSession::Build(session_context_, this));
580 if (syncer_->RetrySyncShare(GetEnabledAndUnthrottledTypes(),
581 session.get()) &&
582 !sessions::HasSyncerError(
583 session->status_controller().model_neutral_state())) {
584 nudge_tracker_.RecordSuccessfulSyncCycle(base::TimeTicks::Now());
585 } else {
586 HandleFailure(session->status_controller().model_neutral_state());
587 }
588 }
589
579 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { 590 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) {
580 DCHECK(CalledOnValidThread()); 591 DCHECK(CalledOnValidThread());
581 base::TimeTicks now = TimeTicks::Now(); 592 base::TimeTicks now = TimeTicks::Now();
582 // Update timing information for how often datatypes are triggering nudges. 593 // Update timing information for how often datatypes are triggering nudges.
583 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { 594 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) {
584 base::TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()]; 595 base::TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()];
585 last_local_nudges_by_model_type_[iter.Get()] = now; 596 last_local_nudges_by_model_type_[iter.Get()] = now;
586 if (previous.is_null()) 597 if (previous.is_null())
587 continue; 598 continue;
588 599
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 void SyncSchedulerImpl::TrySyncSessionJobImpl() { 687 void SyncSchedulerImpl::TrySyncSessionJobImpl() {
677 JobPriority priority = next_sync_session_job_priority_; 688 JobPriority priority = next_sync_session_job_priority_;
678 next_sync_session_job_priority_ = NORMAL_PRIORITY; 689 next_sync_session_job_priority_ = NORMAL_PRIORITY;
679 690
680 DCHECK(CalledOnValidThread()); 691 DCHECK(CalledOnValidThread());
681 if (mode_ == CONFIGURATION_MODE) { 692 if (mode_ == CONFIGURATION_MODE) {
682 if (pending_configure_params_) { 693 if (pending_configure_params_) {
683 SDVLOG(2) << "Found pending configure job"; 694 SDVLOG(2) << "Found pending configure job";
684 DoConfigurationSyncSessionJob(priority); 695 DoConfigurationSyncSessionJob(priority);
685 } 696 }
686 } else { 697 } else if (CanRunNudgeJobNow(priority)) {
687 DCHECK(mode_ == NORMAL_MODE); 698 if (nudge_tracker_.IsSyncRequired()) {
688 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(priority)) {
689 SDVLOG(2) << "Found pending nudge job"; 699 SDVLOG(2) << "Found pending nudge job";
690 DoNudgeSyncSessionJob(priority); 700 DoNudgeSyncSessionJob(priority);
701 } else if (nudge_tracker_.IsRetryRequired(base::TimeTicks::Now())) {
702 DoRetrySyncSessionJob();
691 } else if (do_poll_after_credentials_updated_ || 703 } else if (do_poll_after_credentials_updated_ ||
692 ((base::TimeTicks::Now() - last_poll_reset_) >= GetPollInterval())) { 704 ((base::TimeTicks::Now() - last_poll_reset_) >= GetPollInterval())) {
693 DoPollSyncSessionJob(); 705 DoPollSyncSessionJob();
694 // Poll timer fires infrequently. Usually by this time access token is 706 // Poll timer fires infrequently. Usually by this time access token is
695 // already expired and poll job will fail with auth error. Set flag to 707 // already expired and poll job will fail with auth error. Set flag to
696 // retry poll once ProfileSyncService gets new access token, TryCanaryJob 708 // retry poll once ProfileSyncService gets new access token, TryCanaryJob
697 // will be called after access token is retrieved. 709 // will be called after access token is retrieved.
698 if (HttpResponse::SYNC_AUTH_ERROR == 710 if (HttpResponse::SYNC_AUTH_ERROR ==
699 session_context_->connection_manager()->server_status()) { 711 session_context_->connection_manager()->server_status()) {
700 do_poll_after_credentials_updated_ = true; 712 do_poll_after_credentials_updated_ = true;
(...skipping 29 matching lines...) Expand all
730 // timer. If we find that no_scheduling_allowed_ is set here, then 742 // timer. If we find that no_scheduling_allowed_ is set here, then
731 // something is very wrong. Maybe someone mistakenly called us directly, or 743 // something is very wrong. Maybe someone mistakenly called us directly, or
732 // mishandled the book-keeping for no_scheduling_allowed_. 744 // mishandled the book-keeping for no_scheduling_allowed_.
733 NOTREACHED() << "Illegal to schedule job while session in progress."; 745 NOTREACHED() << "Illegal to schedule job while session in progress.";
734 return; 746 return;
735 } 747 }
736 748
737 TrySyncSessionJob(); 749 TrySyncSessionJob();
738 } 750 }
739 751
752 void SyncSchedulerImpl::RetryTimerCallback() {
753 TrySyncSessionJob();
754 }
755
740 void SyncSchedulerImpl::Unthrottle() { 756 void SyncSchedulerImpl::Unthrottle() {
741 DCHECK(CalledOnValidThread()); 757 DCHECK(CalledOnValidThread());
742 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode); 758 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode);
743 759
744 // We're no longer throttled, so clear the wait interval. 760 // We're no longer throttled, so clear the wait interval.
745 wait_interval_.reset(); 761 wait_interval_.reset();
746 NotifyRetryTime(base::Time()); 762 NotifyRetryTime(base::Time());
747 763
748 // We treat this as a 'canary' in the sense that it was originally scheduled 764 // We treat this as a 'canary' in the sense that it was originally scheduled
749 // to run some time ago, failed, and we now want to retry, versus a job that 765 // to run some time ago, failed, and we now want to retry, versus a job that
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 DCHECK(CalledOnValidThread()); 899 DCHECK(CalledOnValidThread());
884 if (ShouldRequestEarlyExit( 900 if (ShouldRequestEarlyExit(
885 snapshot.model_neutral_state().sync_protocol_error)) { 901 snapshot.model_neutral_state().sync_protocol_error)) {
886 SDVLOG(2) << "Sync Scheduler requesting early exit."; 902 SDVLOG(2) << "Sync Scheduler requesting early exit.";
887 Stop(); 903 Stop();
888 } 904 }
889 if (IsActionableError(snapshot.model_neutral_state().sync_protocol_error)) 905 if (IsActionableError(snapshot.model_neutral_state().sync_protocol_error))
890 OnActionableError(snapshot); 906 OnActionableError(snapshot);
891 } 907 }
892 908
909 void SyncSchedulerImpl::OnReceivedGuRetryDelaySeconds(int delay_seconds) {
910 nudge_tracker_.set_next_retry_time(
911 base::TimeTicks::Now() + base::TimeDelta::FromSeconds(delay_seconds));
912 retry_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay_seconds),
913 this, &SyncSchedulerImpl::RetryTimerCallback);
914 }
915
893 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { 916 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) {
894 DCHECK(CalledOnValidThread()); 917 DCHECK(CalledOnValidThread());
895 session_context_->set_notifications_enabled(notifications_enabled); 918 session_context_->set_notifications_enabled(notifications_enabled);
896 if (notifications_enabled) 919 if (notifications_enabled)
897 nudge_tracker_.OnInvalidationsEnabled(); 920 nudge_tracker_.OnInvalidationsEnabled();
898 else 921 else
899 nudge_tracker_.OnInvalidationsDisabled(); 922 nudge_tracker_.OnInvalidationsDisabled();
900 } 923 }
901 924
902 base::TimeDelta SyncSchedulerImpl::GetSessionsCommitDelay() const { 925 base::TimeDelta SyncSchedulerImpl::GetSessionsCommitDelay() const {
903 DCHECK(CalledOnValidThread()); 926 DCHECK(CalledOnValidThread());
904 return sessions_commit_delay_; 927 return sessions_commit_delay_;
905 } 928 }
906 929
907 #undef SDVLOG_LOC 930 #undef SDVLOG_LOC
908 931
909 #undef SDVLOG 932 #undef SDVLOG
910 933
911 #undef SLOG 934 #undef SLOG
912 935
913 #undef ENUM_CASE 936 #undef ENUM_CASE
914 937
915 } // namespace syncer 938 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698