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

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

Issue 146113003: sync: GU retry with less explicit TimeTicks logic (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"
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)), 163 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)),
164 sessions_commit_delay_( 164 sessions_commit_delay_(
165 TimeDelta::FromSeconds(kDefaultSessionsCommitDelaySeconds)), 165 TimeDelta::FromSeconds(kDefaultSessionsCommitDelaySeconds)),
166 mode_(NORMAL_MODE), 166 mode_(NORMAL_MODE),
167 delay_provider_(delay_provider), 167 delay_provider_(delay_provider),
168 syncer_(syncer), 168 syncer_(syncer),
169 session_context_(context), 169 session_context_(context),
170 no_scheduling_allowed_(false), 170 no_scheduling_allowed_(false),
171 do_poll_after_credentials_updated_(false), 171 do_poll_after_credentials_updated_(false),
172 next_sync_session_job_priority_(NORMAL_PRIORITY), 172 next_sync_session_job_priority_(NORMAL_PRIORITY),
173 received_pending_retry_(false),
173 weak_ptr_factory_(this), 174 weak_ptr_factory_(this),
174 weak_ptr_factory_for_weak_handle_(this) { 175 weak_ptr_factory_for_weak_handle_(this) {
175 weak_handle_this_ = MakeWeakHandle( 176 weak_handle_this_ = MakeWeakHandle(
176 weak_ptr_factory_for_weak_handle_.GetWeakPtr()); 177 weak_ptr_factory_for_weak_handle_.GetWeakPtr());
177 } 178 }
178 179
179 SyncSchedulerImpl::~SyncSchedulerImpl() { 180 SyncSchedulerImpl::~SyncSchedulerImpl() {
180 DCHECK(CalledOnValidThread()); 181 DCHECK(CalledOnValidThread());
181 Stop(); 182 Stop();
182 } 183 }
(...skipping 44 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() || nudge_tracker_.IsRetryRequired()) &&
238 nudge_tracker_.IsRetryRequired(base::TimeTicks::Now())) &&
239 CanRunNudgeJobNow(NORMAL_PRIORITY)) { 239 CanRunNudgeJobNow(NORMAL_PRIORITY)) {
240 // We just got back to normal mode. Let's try to run the work that was 240 // We just got back to normal mode. Let's try to run the work that was
241 // queued up while we were configuring. 241 // queued up while we were configuring.
242 TrySyncSessionJob(); 242 TrySyncSessionJob();
243 } 243 }
244 } 244 }
245 245
246 ModelTypeSet SyncSchedulerImpl::GetEnabledAndUnthrottledTypes() { 246 ModelTypeSet SyncSchedulerImpl::GetEnabledAndUnthrottledTypes() {
247 ModelTypeSet enabled_types = session_context_->enabled_types(); 247 ModelTypeSet enabled_types = session_context_->enabled_types();
248 ModelTypeSet throttled_types = nudge_tracker_.GetThrottledTypes(); 248 ModelTypeSet throttled_types = nudge_tracker_.GetThrottledTypes();
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 ENUM_CASE(CONFIGURATION_MODE); 445 ENUM_CASE(CONFIGURATION_MODE);
446 ENUM_CASE(NORMAL_MODE); 446 ENUM_CASE(NORMAL_MODE);
447 } 447 }
448 return ""; 448 return "";
449 } 449 }
450 450
451 void SyncSchedulerImpl::DoNudgeSyncSessionJob(JobPriority priority) { 451 void SyncSchedulerImpl::DoNudgeSyncSessionJob(JobPriority priority) {
452 DCHECK(CalledOnValidThread()); 452 DCHECK(CalledOnValidThread());
453 DCHECK(CanRunNudgeJobNow(priority)); 453 DCHECK(CanRunNudgeJobNow(priority));
454 454
455 // Clear pending retry flag in case it was stale.
456 ClearReceivedGuRetryDelayFlag();
457
455 DVLOG(2) << "Will run normal mode sync cycle with types " 458 DVLOG(2) << "Will run normal mode sync cycle with types "
456 << ModelTypeSetToString(session_context_->enabled_types()); 459 << ModelTypeSetToString(session_context_->enabled_types());
457 scoped_ptr<SyncSession> session(SyncSession::Build(session_context_, this)); 460 scoped_ptr<SyncSession> session(SyncSession::Build(session_context_, this));
458 bool premature_exit = !syncer_->NormalSyncShare( 461 bool premature_exit = !syncer_->NormalSyncShare(
459 GetEnabledAndUnthrottledTypes(), 462 GetEnabledAndUnthrottledTypes(),
460 nudge_tracker_, 463 nudge_tracker_,
461 session.get()); 464 session.get());
462 AdjustPolling(FORCE_RESET); 465 AdjustPolling(FORCE_RESET);
463 // Don't run poll job till the next time poll timer fires. 466 // Don't run poll job till the next time poll timer fires.
464 do_poll_after_credentials_updated_ = false; 467 do_poll_after_credentials_updated_ = false;
465 468
466 bool success = !premature_exit 469 bool success = !premature_exit
467 && !sessions::HasSyncerError( 470 && !sessions::HasSyncerError(
468 session->status_controller().model_neutral_state()); 471 session->status_controller().model_neutral_state());
469 472
470 if (success) { 473 if (success) {
471 // That cycle took care of any outstanding work we had. 474 // That cycle took care of any outstanding work we had.
472 SDVLOG(2) << "Nudge succeeded."; 475 SDVLOG(2) << "Nudge succeeded.";
473 nudge_tracker_.RecordSuccessfulSyncCycle(base::TimeTicks::Now()); 476 nudge_tracker_.RecordSuccessfulSyncCycle();
474 scheduled_nudge_time_ = base::TimeTicks(); 477 scheduled_nudge_time_ = base::TimeTicks();
475 478
476 // If we're here, then we successfully reached the server. End all backoff. 479 // If we're here, then we successfully reached the server. End all backoff.
477 wait_interval_.reset(); 480 wait_interval_.reset();
478 NotifyRetryTime(base::Time()); 481 NotifyRetryTime(base::Time());
479 return; 482
483 // Set the next GU retry time, if the server requested it.
484 ProcessReceivedGuRetryDelay();
haitaol1 2014/01/27 23:17:07 Previously retry may be scheduled even when sync f
rlarocque 2014/01/28 01:06:34 Interesting. I think that makes a few corner case
480 } else { 485 } else {
481 HandleFailure(session->status_controller().model_neutral_state()); 486 HandleFailure(session->status_controller().model_neutral_state());
482 } 487 }
483 } 488 }
484 489
485 void SyncSchedulerImpl::DoConfigurationSyncSessionJob(JobPriority priority) { 490 void SyncSchedulerImpl::DoConfigurationSyncSessionJob(JobPriority priority) {
486 DCHECK(CalledOnValidThread()); 491 DCHECK(CalledOnValidThread());
487 DCHECK_EQ(mode_, CONFIGURATION_MODE); 492 DCHECK_EQ(mode_, CONFIGURATION_MODE);
488 DCHECK(pending_configure_params_ != NULL); 493 DCHECK(pending_configure_params_ != NULL);
489 494
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 578
574 base::AutoReset<bool> protector(&no_scheduling_allowed_, true); 579 base::AutoReset<bool> protector(&no_scheduling_allowed_, true);
575 580
576 SDVLOG(2) << "Retrying with types " 581 SDVLOG(2) << "Retrying with types "
577 << ModelTypeSetToString(GetEnabledAndUnthrottledTypes()); 582 << ModelTypeSetToString(GetEnabledAndUnthrottledTypes());
578 scoped_ptr<SyncSession> session(SyncSession::Build(session_context_, this)); 583 scoped_ptr<SyncSession> session(SyncSession::Build(session_context_, this));
579 if (syncer_->RetrySyncShare(GetEnabledAndUnthrottledTypes(), 584 if (syncer_->RetrySyncShare(GetEnabledAndUnthrottledTypes(),
580 session.get()) && 585 session.get()) &&
581 !sessions::HasSyncerError( 586 !sessions::HasSyncerError(
582 session->status_controller().model_neutral_state())) { 587 session->status_controller().model_neutral_state())) {
583 nudge_tracker_.RecordSuccessfulSyncCycle(base::TimeTicks::Now()); 588 nudge_tracker_.RecordSuccessfulSyncCycle();
584 } else { 589 } else {
585 HandleFailure(session->status_controller().model_neutral_state()); 590 HandleFailure(session->status_controller().model_neutral_state());
586 } 591 }
587 } 592 }
588 593
589 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { 594 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) {
590 DCHECK(CalledOnValidThread()); 595 DCHECK(CalledOnValidThread());
591 base::TimeTicks now = TimeTicks::Now(); 596 base::TimeTicks now = TimeTicks::Now();
592 // Update timing information for how often datatypes are triggering nudges. 597 // Update timing information for how often datatypes are triggering nudges.
593 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { 598 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 // access token will be here. 685 // access token will be here.
681 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 686 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
682 &SyncSchedulerImpl::TrySyncSessionJobImpl, 687 &SyncSchedulerImpl::TrySyncSessionJobImpl,
683 weak_ptr_factory_.GetWeakPtr())); 688 weak_ptr_factory_.GetWeakPtr()));
684 } 689 }
685 690
686 void SyncSchedulerImpl::TrySyncSessionJobImpl() { 691 void SyncSchedulerImpl::TrySyncSessionJobImpl() {
687 JobPriority priority = next_sync_session_job_priority_; 692 JobPriority priority = next_sync_session_job_priority_;
688 next_sync_session_job_priority_ = NORMAL_PRIORITY; 693 next_sync_session_job_priority_ = NORMAL_PRIORITY;
689 694
695 nudge_tracker_.ToggleRetryFlagIfRequired(base::TimeTicks::Now());
696
690 DCHECK(CalledOnValidThread()); 697 DCHECK(CalledOnValidThread());
691 if (mode_ == CONFIGURATION_MODE) { 698 if (mode_ == CONFIGURATION_MODE) {
692 if (pending_configure_params_) { 699 if (pending_configure_params_) {
693 SDVLOG(2) << "Found pending configure job"; 700 SDVLOG(2) << "Found pending configure job";
694 DoConfigurationSyncSessionJob(priority); 701 DoConfigurationSyncSessionJob(priority);
695 } 702 }
696 } else if (CanRunNudgeJobNow(priority)) { 703 } else if (CanRunNudgeJobNow(priority)) {
697 if (nudge_tracker_.IsSyncRequired()) { 704 if (nudge_tracker_.IsSyncRequired()) {
698 SDVLOG(2) << "Found pending nudge job"; 705 SDVLOG(2) << "Found pending nudge job";
699 DoNudgeSyncSessionJob(priority); 706 DoNudgeSyncSessionJob(priority);
700 } else if (nudge_tracker_.IsRetryRequired(base::TimeTicks::Now())) { 707 } else if (nudge_tracker_.IsRetryRequired()) {
701 DoRetrySyncSessionJob(); 708 DoRetrySyncSessionJob();
702 } else if (do_poll_after_credentials_updated_ || 709 } else if (do_poll_after_credentials_updated_ ||
703 ((base::TimeTicks::Now() - last_poll_reset_) >= GetPollInterval())) { 710 ((base::TimeTicks::Now() - last_poll_reset_) >= GetPollInterval())) {
704 DoPollSyncSessionJob(); 711 DoPollSyncSessionJob();
705 // Poll timer fires infrequently. Usually by this time access token is 712 // Poll timer fires infrequently. Usually by this time access token is
706 // already expired and poll job will fail with auth error. Set flag to 713 // already expired and poll job will fail with auth error. Set flag to
707 // retry poll once ProfileSyncService gets new access token, TryCanaryJob 714 // retry poll once ProfileSyncService gets new access token, TryCanaryJob
708 // will be called after access token is retrieved. 715 // will be called after access token is retrieved.
709 if (HttpResponse::SYNC_AUTH_ERROR == 716 if (HttpResponse::SYNC_AUTH_ERROR ==
710 session_context_->connection_manager()->server_status()) { 717 session_context_->connection_manager()->server_status()) {
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 if (ShouldRequestEarlyExit( 906 if (ShouldRequestEarlyExit(
900 snapshot.model_neutral_state().sync_protocol_error)) { 907 snapshot.model_neutral_state().sync_protocol_error)) {
901 SDVLOG(2) << "Sync Scheduler requesting early exit."; 908 SDVLOG(2) << "Sync Scheduler requesting early exit.";
902 Stop(); 909 Stop();
903 } 910 }
904 if (IsActionableError(snapshot.model_neutral_state().sync_protocol_error)) 911 if (IsActionableError(snapshot.model_neutral_state().sync_protocol_error))
905 OnActionableError(snapshot); 912 OnActionableError(snapshot);
906 } 913 }
907 914
908 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const base::TimeDelta& delay) { 915 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const base::TimeDelta& delay) {
909 nudge_tracker_.set_next_retry_time(base::TimeTicks::Now() + delay); 916 // We'll deal with this after the sync cycle is complete.
910 retry_timer_.Start(FROM_HERE, delay, this, 917 received_pending_retry_ = true;
haitaol1 2014/01/27 23:17:07 Why change this? Previous implementation is simple
rlarocque 2014/01/28 01:06:34 Agreed, it is complicated. Pavel made similar com
911 &SyncSchedulerImpl::RetryTimerCallback); 918 pending_retry_delay_ = delay;
919 }
920
921 void SyncSchedulerImpl::ProcessReceivedGuRetryDelay() {
922 if (received_pending_retry_) {
923 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + pending_retry_delay_);
924 retry_timer_.Start(FROM_HERE, pending_retry_delay_, this,
925 &SyncSchedulerImpl::RetryTimerCallback);
926 }
pavely 2014/01/27 11:54:05 Not required for this change but I would put "rece
927 }
928
929 void SyncSchedulerImpl::ClearReceivedGuRetryDelayFlag() {
930 received_pending_retry_ = false;
912 } 931 }
913 932
914 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { 933 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) {
915 DCHECK(CalledOnValidThread()); 934 DCHECK(CalledOnValidThread());
916 session_context_->set_notifications_enabled(notifications_enabled); 935 session_context_->set_notifications_enabled(notifications_enabled);
917 if (notifications_enabled) 936 if (notifications_enabled)
918 nudge_tracker_.OnInvalidationsEnabled(); 937 nudge_tracker_.OnInvalidationsEnabled();
919 else 938 else
920 nudge_tracker_.OnInvalidationsDisabled(); 939 nudge_tracker_.OnInvalidationsDisabled();
921 } 940 }
922 941
923 base::TimeDelta SyncSchedulerImpl::GetSessionsCommitDelay() const { 942 base::TimeDelta SyncSchedulerImpl::GetSessionsCommitDelay() const {
924 DCHECK(CalledOnValidThread()); 943 DCHECK(CalledOnValidThread());
925 return sessions_commit_delay_; 944 return sessions_commit_delay_;
926 } 945 }
927 946
928 #undef SDVLOG_LOC 947 #undef SDVLOG_LOC
929 948
930 #undef SDVLOG 949 #undef SDVLOG
931 950
932 #undef SLOG 951 #undef SLOG
933 952
934 #undef ENUM_CASE 953 #undef ENUM_CASE
935 954
936 } // namespace syncer 955 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698