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 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
230 Mode old_mode = mode_; | 230 Mode old_mode = mode_; |
231 mode_ = mode; | 231 mode_ = mode; |
232 AdjustPolling(UPDATE_INTERVAL); // Will kick start poll timer if needed. | 232 AdjustPolling(UPDATE_INTERVAL); // Will kick start poll timer if needed. |
233 | 233 |
234 if (old_mode != mode_ && | 234 if (old_mode != mode_ && |
235 mode_ == NORMAL_MODE && | 235 mode_ == NORMAL_MODE && |
236 nudge_tracker_.IsSyncRequired() && | 236 nudge_tracker_.IsSyncRequired() && |
237 CanRunNudgeJobNow(NORMAL_PRIORITY)) { | 237 CanRunNudgeJobNow(NORMAL_PRIORITY)) { |
238 // We just got back to normal mode. Let's try to run the work that was | 238 // We just got back to normal mode. Let's try to run the work that was |
239 // queued up while we were configuring. | 239 // queued up while we were configuring. |
240 DoNudgeSyncSessionJob(NORMAL_PRIORITY); | 240 TryJob(NORMAL_PRIORITY); |
241 } | 241 } |
242 } | 242 } |
243 | 243 |
244 ModelTypeSet SyncSchedulerImpl::GetEnabledAndUnthrottledTypes() { | 244 ModelTypeSet SyncSchedulerImpl::GetEnabledAndUnthrottledTypes() { |
245 ModelTypeSet enabled_types = | 245 ModelTypeSet enabled_types = |
246 GetRoutingInfoTypes(session_context_->routing_info()); | 246 GetRoutingInfoTypes(session_context_->routing_info()); |
247 ModelTypeSet throttled_types = | 247 ModelTypeSet throttled_types = |
248 nudge_tracker_.GetThrottledTypes(); | 248 nudge_tracker_.GetThrottledTypes(); |
249 return Difference(enabled_types, throttled_types); | 249 return Difference(enabled_types, throttled_types); |
250 } | 250 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 | 292 |
293 ModelSafeRoutingInfo restricted_routes; | 293 ModelSafeRoutingInfo restricted_routes; |
294 BuildModelSafeParams(params.types_to_download, | 294 BuildModelSafeParams(params.types_to_download, |
295 params.routing_info, | 295 params.routing_info, |
296 &restricted_routes); | 296 &restricted_routes); |
297 session_context_->set_routing_info(restricted_routes); | 297 session_context_->set_routing_info(restricted_routes); |
298 | 298 |
299 // Only reconfigure if we have types to download. | 299 // Only reconfigure if we have types to download. |
300 if (!params.types_to_download.Empty()) { | 300 if (!params.types_to_download.Empty()) { |
301 pending_configure_params_.reset(new ConfigurationParams(params)); | 301 pending_configure_params_.reset(new ConfigurationParams(params)); |
302 DoConfigurationSyncSessionJob(NORMAL_PRIORITY); | 302 TryJob(NORMAL_PRIORITY); |
303 } else { | 303 } else { |
304 SDVLOG(2) << "No change in routing info, calling ready task directly."; | 304 SDVLOG(2) << "No change in routing info, calling ready task directly."; |
305 params.ready_task.Run(); | 305 params.ready_task.Run(); |
306 } | 306 } |
307 } | 307 } |
308 | 308 |
309 bool SyncSchedulerImpl::CanRunJobNow(JobPriority priority) { | 309 bool SyncSchedulerImpl::CanRunJobNow(JobPriority priority) { |
310 DCHECK(CalledOnValidThread()); | 310 DCHECK(CalledOnValidThread()); |
311 if (wait_interval_ && wait_interval_->mode == WaitInterval::THROTTLED) { | 311 if (wait_interval_ && wait_interval_->mode == WaitInterval::THROTTLED) { |
312 SDVLOG(1) << "Unable to run a job because we're throttled."; | 312 SDVLOG(1) << "Unable to run a job because we're throttled."; |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 return; | 565 return; |
566 } | 566 } |
567 | 567 |
568 SDVLOG(2) << "Polling with routes " | 568 SDVLOG(2) << "Polling with routes " |
569 << ModelSafeRoutingInfoToString(session_context_->routing_info()); | 569 << ModelSafeRoutingInfoToString(session_context_->routing_info()); |
570 scoped_ptr<SyncSession> session(SyncSession::Build(session_context_, this)); | 570 scoped_ptr<SyncSession> session(SyncSession::Build(session_context_, this)); |
571 syncer_->PollSyncShare( | 571 syncer_->PollSyncShare( |
572 GetEnabledAndUnthrottledTypes(), | 572 GetEnabledAndUnthrottledTypes(), |
573 session.get()); | 573 session.get()); |
574 | 574 |
575 AdjustPolling(UPDATE_INTERVAL); | 575 AdjustPolling(FORCE_RESET); |
576 | 576 |
577 if (IsCurrentlyThrottled()) { | 577 if (IsCurrentlyThrottled()) { |
578 SDVLOG(2) << "Poll request got us throttled."; | 578 SDVLOG(2) << "Poll request got us throttled."; |
579 // The OnSilencedUntil() call set up the WaitInterval for us. All we need | 579 // The OnSilencedUntil() call set up the WaitInterval for us. All we need |
580 // to do is start the timer. | 580 // to do is start the timer. |
581 RestartWaiting(); | 581 RestartWaiting(); |
582 } | 582 } |
583 } | 583 } |
584 | 584 |
585 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { | 585 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { |
586 DCHECK(CalledOnValidThread()); | 586 DCHECK(CalledOnValidThread()); |
587 base::TimeTicks now = TimeTicks::Now(); | 587 base::TimeTicks now = TimeTicks::Now(); |
588 // Update timing information for how often datatypes are triggering nudges. | 588 // Update timing information for how often datatypes are triggering nudges. |
589 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { | 589 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { |
590 base::TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()]; | 590 base::TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()]; |
591 last_local_nudges_by_model_type_[iter.Get()] = now; | 591 last_local_nudges_by_model_type_[iter.Get()] = now; |
592 if (previous.is_null()) | 592 if (previous.is_null()) |
593 continue; | 593 continue; |
594 | 594 |
595 #define PER_DATA_TYPE_MACRO(type_str) \ | 595 #define PER_DATA_TYPE_MACRO(type_str) \ |
596 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); | 596 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); |
597 SYNC_DATA_TYPE_HISTOGRAM(iter.Get()); | 597 SYNC_DATA_TYPE_HISTOGRAM(iter.Get()); |
598 #undef PER_DATA_TYPE_MACRO | 598 #undef PER_DATA_TYPE_MACRO |
599 } | 599 } |
600 } | 600 } |
601 | 601 |
602 TimeDelta SyncSchedulerImpl::GetPollInterval() { | |
603 return (!session_context_->notifications_enabled() || | |
604 !session_context_->ShouldFetchUpdatesBeforeCommit()) ? | |
605 syncer_short_poll_interval_seconds_ : | |
606 syncer_long_poll_interval_seconds_; | |
607 } | |
608 | |
602 void SyncSchedulerImpl::AdjustPolling(PollAdjustType type) { | 609 void SyncSchedulerImpl::AdjustPolling(PollAdjustType type) { |
603 DCHECK(CalledOnValidThread()); | 610 DCHECK(CalledOnValidThread()); |
604 | 611 |
605 TimeDelta poll = (!session_context_->notifications_enabled() || | 612 TimeDelta poll = GetPollInterval(); |
606 !session_context_->ShouldFetchUpdatesBeforeCommit()) ? | |
607 syncer_short_poll_interval_seconds_ : | |
608 syncer_long_poll_interval_seconds_; | |
609 bool rate_changed = !poll_timer_.IsRunning() || | 613 bool rate_changed = !poll_timer_.IsRunning() || |
610 poll != poll_timer_.GetCurrentDelay(); | 614 poll != poll_timer_.GetCurrentDelay(); |
611 | 615 |
612 if (type == FORCE_RESET && !rate_changed) | 616 if (type == FORCE_RESET) { |
613 poll_timer_.Reset(); | 617 last_poll_reset_ = base::TimeTicks::Now(); |
618 if (!rate_changed) | |
619 poll_timer_.Reset(); | |
620 } | |
614 | 621 |
615 if (!rate_changed) | 622 if (!rate_changed) |
616 return; | 623 return; |
617 | 624 |
618 // Adjust poll rate. | 625 // Adjust poll rate. |
619 poll_timer_.Stop(); | 626 poll_timer_.Stop(); |
620 poll_timer_.Start(FROM_HERE, poll, this, | 627 poll_timer_.Start(FROM_HERE, poll, this, |
621 &SyncSchedulerImpl::PollTimerCallback); | 628 &SyncSchedulerImpl::PollTimerCallback); |
622 } | 629 } |
623 | 630 |
(...skipping 29 matching lines...) Expand all Loading... | |
653 poll_timer_.Stop(); | 660 poll_timer_.Stop(); |
654 pending_wakeup_timer_.Stop(); | 661 pending_wakeup_timer_.Stop(); |
655 pending_configure_params_.reset(); | 662 pending_configure_params_.reset(); |
656 if (started_) | 663 if (started_) |
657 started_ = false; | 664 started_ = false; |
658 } | 665 } |
659 | 666 |
660 // This is the only place where we invoke DoSyncSessionJob with canary | 667 // This is the only place where we invoke DoSyncSessionJob with canary |
661 // privileges. Everyone else should use NORMAL_PRIORITY. | 668 // privileges. Everyone else should use NORMAL_PRIORITY. |
662 void SyncSchedulerImpl::TryCanaryJob() { | 669 void SyncSchedulerImpl::TryCanaryJob() { |
663 DCHECK(CalledOnValidThread()); | 670 TryJob(CANARY_PRIORITY); |
664 | |
665 if (mode_ == CONFIGURATION_MODE && pending_configure_params_) { | |
666 SDVLOG(2) << "Found pending configure job; will run as canary"; | |
667 DoConfigurationSyncSessionJob(CANARY_PRIORITY); | |
668 } else if (mode_ == NORMAL_MODE && nudge_tracker_.IsSyncRequired() && | |
669 CanRunNudgeJobNow(CANARY_PRIORITY)) { | |
670 SDVLOG(2) << "Found pending nudge job; will run as canary"; | |
671 DoNudgeSyncSessionJob(CANARY_PRIORITY); | |
672 } else if (mode_ == NORMAL_MODE && CanRunJobNow(CANARY_PRIORITY) && | |
673 do_poll_after_credentials_updated_) { | |
674 // Retry poll if poll timer recently fired and ProfileSyncService received | |
675 // fresh access token. | |
676 DoPollSyncSessionJob(); | |
677 } else { | |
678 SDVLOG(2) << "Found no work to do; will not run a canary"; | |
679 } | |
680 // Don't run poll job till the next time poll timer fires. | 671 // Don't run poll job till the next time poll timer fires. |
681 do_poll_after_credentials_updated_ = false; | 672 do_poll_after_credentials_updated_ = false; |
682 } | 673 } |
683 | 674 |
675 void SyncSchedulerImpl::TryJob(JobPriority priority) { | |
tim (not reviewing)
2013/11/17 00:36:47
I like it. I've always been a fan of having a cons
pavely
2013/11/18 18:39:55
Done.
| |
676 DCHECK(CalledOnValidThread()); | |
677 if (mode_ == CONFIGURATION_MODE) { | |
678 if (pending_configure_params_) { | |
679 SDVLOG(2) << "Found pending configure job"; | |
680 DoConfigurationSyncSessionJob(priority); | |
681 } | |
682 } else { | |
683 DCHECK(mode_ == NORMAL_MODE); | |
684 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(priority)) { | |
685 SDVLOG(2) << "Found pending nudge job"; | |
686 DoNudgeSyncSessionJob(priority); | |
687 } else if (((base::TimeTicks::Now() - last_poll_reset_) | |
688 >= GetPollInterval()) || do_poll_after_credentials_updated_) { | |
tim (not reviewing)
2013/11/17 00:36:47
Whoa, this is hard to read. Consider pulling Now(
pavely
2013/11/18 18:39:55
I reordered conditions, decided not to extract sub
| |
689 DoPollSyncSessionJob(); | |
690 } | |
691 } | |
692 } | |
693 | |
684 void SyncSchedulerImpl::PollTimerCallback() { | 694 void SyncSchedulerImpl::PollTimerCallback() { |
685 DCHECK(CalledOnValidThread()); | 695 DCHECK(CalledOnValidThread()); |
686 if (no_scheduling_allowed_) { | 696 if (no_scheduling_allowed_) { |
687 // The no_scheduling_allowed_ flag is set by a function-scoped AutoReset in | 697 // The no_scheduling_allowed_ flag is set by a function-scoped AutoReset in |
688 // functions that are called only on the sync thread. This function is also | 698 // functions that are called only on the sync thread. This function is also |
689 // called only on the sync thread, and only when it is posted by an expiring | 699 // called only on the sync thread, and only when it is posted by an expiring |
690 // timer. If we find that no_scheduling_allowed_ is set here, then | 700 // timer. If we find that no_scheduling_allowed_ is set here, then |
691 // something is very wrong. Maybe someone mistakenly called us directly, or | 701 // something is very wrong. Maybe someone mistakenly called us directly, or |
692 // mishandled the book-keeping for no_scheduling_allowed_. | 702 // mishandled the book-keeping for no_scheduling_allowed_. |
693 NOTREACHED() << "Illegal to schedule job while session in progress."; | 703 NOTREACHED() << "Illegal to schedule job while session in progress."; |
694 return; | 704 return; |
695 } | 705 } |
696 | 706 |
697 DoPollSyncSessionJob(); | 707 TryJob(NORMAL_PRIORITY); |
698 // Poll timer fires infrequently. Usually by this time access token is already | 708 // Poll timer fires infrequently. Usually by this time access token is already |
699 // expired and poll job will fail with auth error. Set flag to retry poll once | 709 // expired and poll job will fail with auth error. Set flag to retry poll once |
700 // ProfileSyncService gets new access token, TryCanaryJob will be called in | 710 // ProfileSyncService gets new access token, TryCanaryJob will be called in |
701 // this case. | 711 // this case. |
702 if (HttpResponse::SYNC_AUTH_ERROR == | 712 if (HttpResponse::SYNC_AUTH_ERROR == |
703 session_context_->connection_manager()->server_status()) { | 713 session_context_->connection_manager()->server_status()) { |
704 do_poll_after_credentials_updated_ = true; | 714 do_poll_after_credentials_updated_ = true; |
705 } | 715 } |
706 } | 716 } |
707 | 717 |
(...skipping 24 matching lines...) Expand all Loading... | |
732 type_unthrottle_timer_.Start( | 742 type_unthrottle_timer_.Start( |
733 FROM_HERE, | 743 FROM_HERE, |
734 time_until_next_unthrottle, | 744 time_until_next_unthrottle, |
735 base::Bind(&SyncSchedulerImpl::TypeUnthrottle, | 745 base::Bind(&SyncSchedulerImpl::TypeUnthrottle, |
736 weak_ptr_factory_.GetWeakPtr(), | 746 weak_ptr_factory_.GetWeakPtr(), |
737 unthrottle_time + time_until_next_unthrottle)); | 747 unthrottle_time + time_until_next_unthrottle)); |
738 } | 748 } |
739 | 749 |
740 // Maybe this is a good time to run a nudge job. Let's try it. | 750 // Maybe this is a good time to run a nudge job. Let's try it. |
741 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) | 751 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) |
742 DoNudgeSyncSessionJob(NORMAL_PRIORITY); | 752 TryJob(NORMAL_PRIORITY); |
743 } | 753 } |
744 | 754 |
745 void SyncSchedulerImpl::PerformDelayedNudge() { | 755 void SyncSchedulerImpl::PerformDelayedNudge() { |
746 // Circumstances may have changed since we scheduled this delayed nudge. | 756 // Circumstances may have changed since we scheduled this delayed nudge. |
747 // We must check to see if it's OK to run the job before we do so. | 757 // We must check to see if it's OK to run the job before we do so. |
748 if (CanRunNudgeJobNow(NORMAL_PRIORITY)) | 758 if (CanRunNudgeJobNow(NORMAL_PRIORITY)) |
749 DoNudgeSyncSessionJob(NORMAL_PRIORITY); | 759 TryJob(NORMAL_PRIORITY); |
750 | 760 |
751 // We're not responsible for setting up any retries here. The functions that | 761 // We're not responsible for setting up any retries here. The functions that |
752 // first put us into a state that prevents successful sync cycles (eg. global | 762 // first put us into a state that prevents successful sync cycles (eg. global |
753 // throttling, type throttling, network errors, transient errors) will also | 763 // throttling, type throttling, network errors, transient errors) will also |
754 // setup the appropriate retry logic (eg. retry after timeout, exponential | 764 // setup the appropriate retry logic (eg. retry after timeout, exponential |
755 // backoff, retry when the network changes). | 765 // backoff, retry when the network changes). |
756 } | 766 } |
757 | 767 |
758 void SyncSchedulerImpl::ExponentialBackoffRetry() { | 768 void SyncSchedulerImpl::ExponentialBackoffRetry() { |
759 TryCanaryJob(); | 769 TryCanaryJob(); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
886 | 896 |
887 #undef SDVLOG_LOC | 897 #undef SDVLOG_LOC |
888 | 898 |
889 #undef SDVLOG | 899 #undef SDVLOG |
890 | 900 |
891 #undef SLOG | 901 #undef SLOG |
892 | 902 |
893 #undef ENUM_CASE | 903 #undef ENUM_CASE |
894 | 904 |
895 } // namespace syncer | 905 } // namespace syncer |
OLD | NEW |