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