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 "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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |