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/bind.h" | 10 #include "base/bind.h" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 from_here(from_here) { | 125 from_here(from_here) { |
126 } | 126 } |
127 | 127 |
128 const char* SyncSchedulerImpl::SyncSessionJob::GetPurposeString( | 128 const char* SyncSchedulerImpl::SyncSessionJob::GetPurposeString( |
129 SyncSchedulerImpl::SyncSessionJob::SyncSessionJobPurpose purpose) { | 129 SyncSchedulerImpl::SyncSessionJob::SyncSessionJobPurpose purpose) { |
130 switch (purpose) { | 130 switch (purpose) { |
131 ENUM_CASE(UNKNOWN); | 131 ENUM_CASE(UNKNOWN); |
132 ENUM_CASE(POLL); | 132 ENUM_CASE(POLL); |
133 ENUM_CASE(NUDGE); | 133 ENUM_CASE(NUDGE); |
134 ENUM_CASE(CONFIGURATION); | 134 ENUM_CASE(CONFIGURATION); |
| 135 ENUM_CASE(CLEANUP_DISABLED_TYPES); |
135 } | 136 } |
136 NOTREACHED(); | 137 NOTREACHED(); |
137 return ""; | 138 return ""; |
138 } | 139 } |
139 | 140 |
140 TimeDelta SyncSchedulerImpl::DelayProvider::GetDelay( | 141 TimeDelta SyncSchedulerImpl::DelayProvider::GetDelay( |
141 const base::TimeDelta& last_delay) { | 142 const base::TimeDelta& last_delay) { |
142 return SyncSchedulerImpl::GetRecommendedDelay(last_delay); | 143 return SyncSchedulerImpl::GetRecommendedDelay(last_delay); |
143 } | 144 } |
144 | 145 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 // crbug.com/133030 | 347 // crbug.com/133030 |
347 ModelSafeRoutingInfo restricted_routes; | 348 ModelSafeRoutingInfo restricted_routes; |
348 std::vector<ModelSafeWorker*> restricted_workers; | 349 std::vector<ModelSafeWorker*> restricted_workers; |
349 BuildModelSafeParams(params.types_to_download, | 350 BuildModelSafeParams(params.types_to_download, |
350 params.routing_info, | 351 params.routing_info, |
351 session_context_->workers(), | 352 session_context_->workers(), |
352 &restricted_routes, | 353 &restricted_routes, |
353 &restricted_workers); | 354 &restricted_workers); |
354 session_context_->set_routing_info(params.routing_info); | 355 session_context_->set_routing_info(params.routing_info); |
355 | 356 |
| 357 // We rely on this not failing, so don't need to worry about checking for |
| 358 // success. In addition, this will be removed as part of crbug.com/131433. |
| 359 SyncSessionJob cleanup_job( |
| 360 SyncSessionJob::CLEANUP_DISABLED_TYPES, |
| 361 TimeTicks::Now(), |
| 362 make_linked_ptr(CreateSyncSession(SyncSourceInfo())), |
| 363 false, |
| 364 ConfigurationParams(), |
| 365 FROM_HERE); |
| 366 DoSyncSessionJob(cleanup_job); |
| 367 |
356 if (params.keystore_key_status == ConfigurationParams::KEYSTORE_KEY_NEEDED) { | 368 if (params.keystore_key_status == ConfigurationParams::KEYSTORE_KEY_NEEDED) { |
357 // TODO(zea): implement in such a way that we can handle failures and the | 369 // TODO(zea): implement in such a way that we can handle failures and the |
358 // subsequent retrys the scheduler might perform. See crbug.com/129665. | 370 // subsequent retrys the scheduler might perform. See crbug.com/129665. |
359 NOTIMPLEMENTED(); | 371 NOTIMPLEMENTED(); |
360 } | 372 } |
361 | 373 |
362 // Only reconfigure if we have types to download. | 374 // Only reconfigure if we have types to download. |
363 if (!params.types_to_download.Empty()) { | 375 if (!params.types_to_download.Empty()) { |
364 DCHECK(!restricted_routes.empty()); | 376 DCHECK(!restricted_routes.empty()); |
365 linked_ptr<SyncSession> session(new SyncSession( | 377 linked_ptr<SyncSession> session(new SyncSession( |
(...skipping 26 matching lines...) Expand all Loading... |
392 } | 404 } |
393 | 405 |
394 return true; | 406 return true; |
395 } | 407 } |
396 | 408 |
397 SyncSchedulerImpl::JobProcessDecision | 409 SyncSchedulerImpl::JobProcessDecision |
398 SyncSchedulerImpl::DecideWhileInWaitInterval( | 410 SyncSchedulerImpl::DecideWhileInWaitInterval( |
399 const SyncSessionJob& job) { | 411 const SyncSessionJob& job) { |
400 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 412 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
401 DCHECK(wait_interval_.get()); | 413 DCHECK(wait_interval_.get()); |
| 414 DCHECK_NE(job.purpose, SyncSessionJob::CLEANUP_DISABLED_TYPES); |
402 | 415 |
403 SDVLOG(2) << "DecideWhileInWaitInterval with WaitInterval mode " | 416 SDVLOG(2) << "DecideWhileInWaitInterval with WaitInterval mode " |
404 << WaitInterval::GetModeString(wait_interval_->mode) | 417 << WaitInterval::GetModeString(wait_interval_->mode) |
405 << (wait_interval_->had_nudge ? " (had nudge)" : "") | 418 << (wait_interval_->had_nudge ? " (had nudge)" : "") |
406 << (job.is_canary_job ? " (canary)" : ""); | 419 << (job.is_canary_job ? " (canary)" : ""); |
407 | 420 |
408 if (job.purpose == SyncSessionJob::POLL) | 421 if (job.purpose == SyncSessionJob::POLL) |
409 return DROP; | 422 return DROP; |
410 | 423 |
411 DCHECK(job.purpose == SyncSessionJob::NUDGE || | 424 DCHECK(job.purpose == SyncSessionJob::NUDGE || |
(...skipping 12 matching lines...) Expand all Loading... |
424 return wait_interval_->had_nudge ? DROP : CONTINUE; | 437 return wait_interval_->had_nudge ? DROP : CONTINUE; |
425 else // We are here because timer ran out. So retry. | 438 else // We are here because timer ran out. So retry. |
426 return CONTINUE; | 439 return CONTINUE; |
427 } | 440 } |
428 return job.is_canary_job ? CONTINUE : SAVE; | 441 return job.is_canary_job ? CONTINUE : SAVE; |
429 } | 442 } |
430 | 443 |
431 SyncSchedulerImpl::JobProcessDecision SyncSchedulerImpl::DecideOnJob( | 444 SyncSchedulerImpl::JobProcessDecision SyncSchedulerImpl::DecideOnJob( |
432 const SyncSessionJob& job) { | 445 const SyncSessionJob& job) { |
433 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 446 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 447 if (job.purpose == SyncSessionJob::CLEANUP_DISABLED_TYPES) |
| 448 return CONTINUE; |
434 | 449 |
435 // See if our type is throttled. | 450 // See if our type is throttled. |
436 ModelTypeSet throttled_types = | 451 ModelTypeSet throttled_types = |
437 session_context_->throttled_data_type_tracker()->GetThrottledTypes(); | 452 session_context_->throttled_data_type_tracker()->GetThrottledTypes(); |
438 if (job.purpose == SyncSessionJob::NUDGE && | 453 if (job.purpose == SyncSessionJob::NUDGE && |
439 job.session->source().updates_source == GetUpdatesCallerInfo::LOCAL) { | 454 job.session->source().updates_source == GetUpdatesCallerInfo::LOCAL) { |
440 ModelTypeSet requested_types; | 455 ModelTypeSet requested_types; |
441 for (ModelTypePayloadMap::const_iterator i = | 456 for (ModelTypePayloadMap::const_iterator i = |
442 job.session->source().types.begin(); | 457 job.session->source().types.begin(); |
443 i != job.session->source().types.end(); | 458 i != job.session->source().types.end(); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 | 532 |
518 DCHECK(job.purpose == SyncSessionJob::NUDGE || job.purpose == | 533 DCHECK(job.purpose == SyncSessionJob::NUDGE || job.purpose == |
519 SyncSessionJob::CONFIGURATION); | 534 SyncSessionJob::CONFIGURATION); |
520 | 535 |
521 SaveJob(job); | 536 SaveJob(job); |
522 return false; | 537 return false; |
523 } | 538 } |
524 | 539 |
525 void SyncSchedulerImpl::SaveJob(const SyncSessionJob& job) { | 540 void SyncSchedulerImpl::SaveJob(const SyncSessionJob& job) { |
526 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 541 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 542 // TODO(sync): Should we also check that job.purpose != |
| 543 // CLEANUP_DISABLED_TYPES? (See http://crbug.com/90868.) |
527 if (job.purpose == SyncSessionJob::NUDGE) { | 544 if (job.purpose == SyncSessionJob::NUDGE) { |
528 SDVLOG(2) << "Saving a nudge job"; | 545 SDVLOG(2) << "Saving a nudge job"; |
529 InitOrCoalescePendingJob(job); | 546 InitOrCoalescePendingJob(job); |
530 } else if (job.purpose == SyncSessionJob::CONFIGURATION){ | 547 } else if (job.purpose == SyncSessionJob::CONFIGURATION){ |
531 SDVLOG(2) << "Saving a configuration job"; | 548 SDVLOG(2) << "Saving a configuration job"; |
532 DCHECK(wait_interval_.get()); | 549 DCHECK(wait_interval_.get()); |
533 DCHECK(mode_ == CONFIGURATION_MODE); | 550 DCHECK(mode_ == CONFIGURATION_MODE); |
534 | 551 |
535 // Config params should always get set. | 552 // Config params should always get set. |
536 DCHECK(!job.config_params.ready_task.is_null()); | 553 DCHECK(!job.config_params.ready_task.is_null()); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 switch (purpose) { | 690 switch (purpose) { |
674 case SyncSessionJob::CONFIGURATION: | 691 case SyncSessionJob::CONFIGURATION: |
675 *start = DOWNLOAD_UPDATES; | 692 *start = DOWNLOAD_UPDATES; |
676 *end = APPLY_UPDATES; | 693 *end = APPLY_UPDATES; |
677 return; | 694 return; |
678 case SyncSessionJob::NUDGE: | 695 case SyncSessionJob::NUDGE: |
679 case SyncSessionJob::POLL: | 696 case SyncSessionJob::POLL: |
680 *start = SYNCER_BEGIN; | 697 *start = SYNCER_BEGIN; |
681 *end = SYNCER_END; | 698 *end = SYNCER_END; |
682 return; | 699 return; |
| 700 case SyncSessionJob::CLEANUP_DISABLED_TYPES: |
| 701 *start = CLEANUP_DISABLED_TYPES; |
| 702 *end = CLEANUP_DISABLED_TYPES; |
| 703 return; |
683 default: | 704 default: |
684 NOTREACHED(); | 705 NOTREACHED(); |
685 *start = SYNCER_END; | 706 *start = SYNCER_END; |
686 *end = SYNCER_END; | 707 *end = SYNCER_END; |
687 return; | 708 return; |
688 } | 709 } |
689 } | 710 } |
690 | 711 |
691 void SyncSchedulerImpl::PostTask( | 712 void SyncSchedulerImpl::PostTask( |
692 const tracked_objects::Location& from_here, | 713 const tracked_objects::Location& from_here, |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
777 syncer_->SyncShare(job.session.get(), begin, end); | 798 syncer_->SyncShare(job.session.get(), begin, end); |
778 has_more_to_sync = job.session->HasMoreToSync(); | 799 has_more_to_sync = job.session->HasMoreToSync(); |
779 if (has_more_to_sync) | 800 if (has_more_to_sync) |
780 job.session->PrepareForAnotherSyncCycle(); | 801 job.session->PrepareForAnotherSyncCycle(); |
781 } | 802 } |
782 SDVLOG(2) << "Done SyncShare looping."; | 803 SDVLOG(2) << "Done SyncShare looping."; |
783 | 804 |
784 FinishSyncSessionJob(job); | 805 FinishSyncSessionJob(job); |
785 } | 806 } |
786 | 807 |
| 808 void SyncSchedulerImpl::UpdateCarryoverSessionState( |
| 809 const SyncSessionJob& old_job) { |
| 810 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 811 if (old_job.purpose == SyncSessionJob::CONFIGURATION) { |
| 812 // Whatever types were part of a configuration task will have had updates |
| 813 // downloaded. For that reason, we make sure they get recorded in the |
| 814 // event that they get disabled at a later time. |
| 815 ModelSafeRoutingInfo r(session_context_->previous_session_routing_info()); |
| 816 if (!r.empty()) { |
| 817 ModelSafeRoutingInfo temp_r; |
| 818 ModelSafeRoutingInfo old_info(old_job.session->routing_info()); |
| 819 std::set_union(r.begin(), r.end(), old_info.begin(), old_info.end(), |
| 820 std::insert_iterator<ModelSafeRoutingInfo>(temp_r, temp_r.begin())); |
| 821 session_context_->set_previous_session_routing_info(temp_r); |
| 822 } |
| 823 } else { |
| 824 session_context_->set_previous_session_routing_info( |
| 825 old_job.session->routing_info()); |
| 826 } |
| 827 } |
| 828 |
787 void SyncSchedulerImpl::FinishSyncSessionJob(const SyncSessionJob& job) { | 829 void SyncSchedulerImpl::FinishSyncSessionJob(const SyncSessionJob& job) { |
788 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 830 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
789 // Update timing information for how often datatypes are triggering nudges. | 831 // Update timing information for how often datatypes are triggering nudges. |
790 base::TimeTicks now = TimeTicks::Now(); | 832 base::TimeTicks now = TimeTicks::Now(); |
791 if (!last_sync_session_end_time_.is_null()) { | 833 if (!last_sync_session_end_time_.is_null()) { |
792 ModelTypePayloadMap::const_iterator iter; | 834 ModelTypePayloadMap::const_iterator iter; |
793 for (iter = job.session->source().types.begin(); | 835 for (iter = job.session->source().types.begin(); |
794 iter != job.session->source().types.end(); | 836 iter != job.session->source().types.end(); |
795 ++iter) { | 837 ++iter) { |
796 #define PER_DATA_TYPE_MACRO(type_str) \ | 838 #define PER_DATA_TYPE_MACRO(type_str) \ |
797 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, \ | 839 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, \ |
798 now - last_sync_session_end_time_); | 840 now - last_sync_session_end_time_); |
799 SYNC_DATA_TYPE_HISTOGRAM(iter->first); | 841 SYNC_DATA_TYPE_HISTOGRAM(iter->first); |
800 #undef PER_DATA_TYPE_MACRO | 842 #undef PER_DATA_TYPE_MACRO |
801 } | 843 } |
802 } | 844 } |
803 last_sync_session_end_time_ = now; | 845 last_sync_session_end_time_ = now; |
804 | 846 |
805 // Now update the status of the connection from SCM. We need this to decide | 847 // Now update the status of the connection from SCM. We need this to decide |
806 // whether we need to save/run future jobs. The notifications from SCM are not | 848 // whether we need to save/run future jobs. The notifications from SCM are not |
807 // reliable. | 849 // reliable. |
808 // | 850 // |
809 // TODO(rlarocque): crbug.com/110954 | 851 // TODO(rlarocque): crbug.com/110954 |
810 // We should get rid of the notifications and it is probably not needed to | 852 // We should get rid of the notifications and it is probably not needed to |
811 // maintain this status variable in 2 places. We should query it directly from | 853 // maintain this status variable in 2 places. We should query it directly from |
812 // SCM when needed. | 854 // SCM when needed. |
813 ServerConnectionManager* scm = session_context_->connection_manager(); | 855 ServerConnectionManager* scm = session_context_->connection_manager(); |
814 UpdateServerConnectionManagerStatus(scm->server_status()); | 856 UpdateServerConnectionManagerStatus(scm->server_status()); |
815 | 857 |
| 858 UpdateCarryoverSessionState(job); |
816 if (IsSyncingCurrentlySilenced()) { | 859 if (IsSyncingCurrentlySilenced()) { |
817 SDVLOG(2) << "We are currently throttled; not scheduling the next sync."; | 860 SDVLOG(2) << "We are currently throttled; not scheduling the next sync."; |
818 // TODO(sync): Investigate whether we need to check job.purpose | 861 // TODO(sync): Investigate whether we need to check job.purpose |
819 // here; see DCHECKs in SaveJob(). (See http://crbug.com/90868.) | 862 // here; see DCHECKs in SaveJob(). (See http://crbug.com/90868.) |
820 SaveJob(job); | 863 SaveJob(job); |
821 return; // Nothing to do. | 864 return; // Nothing to do. |
822 } else if (job.session->Succeeded() && | 865 } else if (job.session->Succeeded() && |
823 !job.config_params.ready_task.is_null()) { | 866 !job.config_params.ready_task.is_null()) { |
824 // If this was a configuration job with a ready task, invoke it now that | 867 // If this was a configuration job with a ready task, invoke it now that |
825 // we finished successfully. | 868 // we finished successfully. |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1156 | 1199 |
1157 #undef SDVLOG_LOC | 1200 #undef SDVLOG_LOC |
1158 | 1201 |
1159 #undef SDVLOG | 1202 #undef SDVLOG |
1160 | 1203 |
1161 #undef SLOG | 1204 #undef SLOG |
1162 | 1205 |
1163 #undef ENUM_CASE | 1206 #undef ENUM_CASE |
1164 | 1207 |
1165 } // namespace syncer | 1208 } // namespace syncer |
OLD | NEW |