| 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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 !wait_interval_->pending_configure_job.get()); | 284 !wait_interval_->pending_configure_job.get()); |
| 285 } | 285 } |
| 286 | 286 |
| 287 DoPendingJobIfPossible(false); | 287 DoPendingJobIfPossible(false); |
| 288 } | 288 } |
| 289 } | 289 } |
| 290 | 290 |
| 291 void SyncSchedulerImpl::SendInitialSnapshot() { | 291 void SyncSchedulerImpl::SendInitialSnapshot() { |
| 292 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 292 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 293 scoped_ptr<SyncSession> dummy(new SyncSession(session_context_, this, | 293 scoped_ptr<SyncSession> dummy(new SyncSession(session_context_, this, |
| 294 SyncSourceInfo(), ModelSafeRoutingInfo(), | 294 SyncSourceInfo(), ModelSafeRoutingInfo())); |
| 295 std::vector<ModelSafeWorker*>())); | |
| 296 SyncEngineEvent event(SyncEngineEvent::STATUS_CHANGED); | 295 SyncEngineEvent event(SyncEngineEvent::STATUS_CHANGED); |
| 297 event.snapshot = dummy->TakeSnapshot(); | 296 event.snapshot = dummy->TakeSnapshot(); |
| 298 session_context_->NotifyListeners(event); | 297 session_context_->NotifyListeners(event); |
| 299 } | 298 } |
| 300 | 299 |
| 301 namespace { | 300 namespace { |
| 302 | 301 |
| 303 // Helper to extract the routing info and workers corresponding to types in | 302 // Helper to extract the routing info and workers corresponding to types in |
| 304 // |types| from |current_routes| and |current_workers|. | 303 // |types| from |current_routes| and |current_workers|. |
| 305 void BuildModelSafeParams( | 304 void BuildModelSafeParams( |
| 306 ModelTypeSet types_to_download, | 305 ModelTypeSet types_to_download, |
| 307 const ModelSafeRoutingInfo& current_routes, | 306 const ModelSafeRoutingInfo& current_routes, |
| 308 const std::vector<ModelSafeWorker*>& current_workers, | 307 const std::vector<ModelSafeWorker*>& current_workers, |
| 309 ModelSafeRoutingInfo* result_routes, | 308 ModelSafeRoutingInfo* result_routes) { |
| 310 std::vector<ModelSafeWorker*>* result_workers) { | |
| 311 std::set<ModelSafeGroup> active_groups; | 309 std::set<ModelSafeGroup> active_groups; |
| 312 active_groups.insert(GROUP_PASSIVE); | 310 active_groups.insert(GROUP_PASSIVE); |
| 313 for (ModelTypeSet::Iterator iter = types_to_download.First(); iter.Good(); | 311 for (ModelTypeSet::Iterator iter = types_to_download.First(); iter.Good(); |
| 314 iter.Inc()) { | 312 iter.Inc()) { |
| 315 ModelType type = iter.Get(); | 313 ModelType type = iter.Get(); |
| 316 ModelSafeRoutingInfo::const_iterator route = current_routes.find(type); | 314 ModelSafeRoutingInfo::const_iterator route = current_routes.find(type); |
| 317 DCHECK(route != current_routes.end()); | 315 DCHECK(route != current_routes.end()); |
| 318 ModelSafeGroup group = route->second; | 316 ModelSafeGroup group = route->second; |
| 319 (*result_routes)[type] = group; | 317 (*result_routes)[type] = group; |
| 320 active_groups.insert(group); | 318 active_groups.insert(group); |
| 321 } | 319 } |
| 322 | |
| 323 for(std::vector<ModelSafeWorker*>::const_iterator iter = | |
| 324 current_workers.begin(); iter != current_workers.end(); ++iter) { | |
| 325 if (active_groups.count((*iter)->GetModelSafeGroup()) > 0) | |
| 326 result_workers->push_back(*iter); | |
| 327 } | |
| 328 } | 320 } |
| 329 | 321 |
| 330 } // namespace. | 322 } // namespace. |
| 331 | 323 |
| 332 bool SyncSchedulerImpl::ScheduleConfiguration( | 324 bool SyncSchedulerImpl::ScheduleConfiguration( |
| 333 const ConfigurationParams& params) { | 325 const ConfigurationParams& params) { |
| 334 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 326 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 335 DCHECK(IsConfigRelatedUpdateSourceValue(params.source)); | 327 DCHECK(IsConfigRelatedUpdateSourceValue(params.source)); |
| 336 DCHECK_EQ(CONFIGURATION_MODE, mode_); | 328 DCHECK_EQ(CONFIGURATION_MODE, mode_); |
| 337 DCHECK(!params.ready_task.is_null()); | 329 DCHECK(!params.ready_task.is_null()); |
| 338 SDVLOG(2) << "Reconfiguring syncer."; | 330 SDVLOG(2) << "Reconfiguring syncer."; |
| 339 | 331 |
| 340 // Only one configuration is allowed at a time. Verify we're not waiting | 332 // Only one configuration is allowed at a time. Verify we're not waiting |
| 341 // for a pending configure job. | 333 // for a pending configure job. |
| 342 DCHECK(!wait_interval_.get() || !wait_interval_->pending_configure_job.get()); | 334 DCHECK(!wait_interval_.get() || !wait_interval_->pending_configure_job.get()); |
| 343 | 335 |
| 344 // TODO(sync): now that ModelChanging commands only use those workers within | 336 // TODO(sync): now that ModelChanging commands only use those workers within |
| 345 // the routing info, we don't really need |restricted_workers|. Remove it. | 337 // the routing info, we don't really need |restricted_workers|. Remove it. |
| 346 // crbug.com/133030 | 338 // crbug.com/133030 |
| 347 ModelSafeRoutingInfo restricted_routes; | 339 ModelSafeRoutingInfo restricted_routes; |
| 348 std::vector<ModelSafeWorker*> restricted_workers; | |
| 349 BuildModelSafeParams(params.types_to_download, | 340 BuildModelSafeParams(params.types_to_download, |
| 350 params.routing_info, | 341 params.routing_info, |
| 351 session_context_->workers(), | 342 session_context_->workers(), |
| 352 &restricted_routes, | 343 &restricted_routes); |
| 353 &restricted_workers); | |
| 354 session_context_->set_routing_info(params.routing_info); | 344 session_context_->set_routing_info(params.routing_info); |
| 355 | 345 |
| 356 // Only reconfigure if we have types to download. | 346 // Only reconfigure if we have types to download. |
| 357 if (!params.types_to_download.Empty()) { | 347 if (!params.types_to_download.Empty()) { |
| 358 DCHECK(!restricted_routes.empty()); | 348 DCHECK(!restricted_routes.empty()); |
| 359 linked_ptr<SyncSession> session(new SyncSession( | 349 linked_ptr<SyncSession> session(new SyncSession( |
| 360 session_context_, | 350 session_context_, |
| 361 this, | 351 this, |
| 362 SyncSourceInfo(params.source, | 352 SyncSourceInfo(params.source, |
| 363 ModelSafeRoutingInfoToStateMap( | 353 ModelSafeRoutingInfoToStateMap( |
| 364 restricted_routes, | 354 restricted_routes, |
| 365 std::string())), | 355 std::string())), |
| 366 restricted_routes, | 356 restricted_routes)); |
| 367 restricted_workers)); | |
| 368 SyncSessionJob job(SyncSessionJob::CONFIGURATION, | 357 SyncSessionJob job(SyncSessionJob::CONFIGURATION, |
| 369 TimeTicks::Now(), | 358 TimeTicks::Now(), |
| 370 session, | 359 session, |
| 371 false, | 360 false, |
| 372 params, | 361 params, |
| 373 FROM_HERE); | 362 FROM_HERE); |
| 374 DoSyncSessionJob(job); | 363 DoSyncSessionJob(job); |
| 375 | 364 |
| 376 // If we failed, the job would have been saved as the pending configure | 365 // If we failed, the job would have been saved as the pending configure |
| 377 // job and a wait interval would have been set. | 366 // job and a wait interval would have been set. |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 void SyncSchedulerImpl::InitOrCoalescePendingJob(const SyncSessionJob& job) { | 495 void SyncSchedulerImpl::InitOrCoalescePendingJob(const SyncSessionJob& job) { |
| 507 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 496 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 508 DCHECK(job.purpose != SyncSessionJob::CONFIGURATION); | 497 DCHECK(job.purpose != SyncSessionJob::CONFIGURATION); |
| 509 if (pending_nudge_.get() == NULL) { | 498 if (pending_nudge_.get() == NULL) { |
| 510 SDVLOG(2) << "Creating a pending nudge job"; | 499 SDVLOG(2) << "Creating a pending nudge job"; |
| 511 SyncSession* s = job.session.get(); | 500 SyncSession* s = job.session.get(); |
| 512 | 501 |
| 513 // Get a fresh session with similar configuration as before (resets | 502 // Get a fresh session with similar configuration as before (resets |
| 514 // StatusController). | 503 // StatusController). |
| 515 scoped_ptr<SyncSession> session(new SyncSession(s->context(), | 504 scoped_ptr<SyncSession> session(new SyncSession(s->context(), |
| 516 s->delegate(), s->source(), s->routing_info(), s->workers())); | 505 s->delegate(), s->source(), s->routing_info())); |
| 517 | 506 |
| 518 SyncSessionJob new_job(SyncSessionJob::NUDGE, job.scheduled_start, | 507 SyncSessionJob new_job(SyncSessionJob::NUDGE, job.scheduled_start, |
| 519 make_linked_ptr(session.release()), false, | 508 make_linked_ptr(session.release()), false, |
| 520 ConfigurationParams(), job.from_here); | 509 ConfigurationParams(), job.from_here); |
| 521 pending_nudge_.reset(new SyncSessionJob(new_job)); | 510 pending_nudge_.reset(new SyncSessionJob(new_job)); |
| 522 return; | 511 return; |
| 523 } | 512 } |
| 524 | 513 |
| 525 SDVLOG(2) << "Coalescing a pending nudge"; | 514 SDVLOG(2) << "Coalescing a pending nudge"; |
| 526 pending_nudge_->session->Coalesce(*(job.session.get())); | 515 pending_nudge_->session->Coalesce(*(job.session.get())); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 556 InitOrCoalescePendingJob(job); | 545 InitOrCoalescePendingJob(job); |
| 557 } else if (job.purpose == SyncSessionJob::CONFIGURATION){ | 546 } else if (job.purpose == SyncSessionJob::CONFIGURATION){ |
| 558 SDVLOG(2) << "Saving a configuration job"; | 547 SDVLOG(2) << "Saving a configuration job"; |
| 559 DCHECK(wait_interval_.get()); | 548 DCHECK(wait_interval_.get()); |
| 560 DCHECK(mode_ == CONFIGURATION_MODE); | 549 DCHECK(mode_ == CONFIGURATION_MODE); |
| 561 | 550 |
| 562 // Config params should always get set. | 551 // Config params should always get set. |
| 563 DCHECK(!job.config_params.ready_task.is_null()); | 552 DCHECK(!job.config_params.ready_task.is_null()); |
| 564 SyncSession* old = job.session.get(); | 553 SyncSession* old = job.session.get(); |
| 565 SyncSession* s(new SyncSession(session_context_, this, old->source(), | 554 SyncSession* s(new SyncSession(session_context_, this, old->source(), |
| 566 old->routing_info(), old->workers())); | 555 old->routing_info())); |
| 567 SyncSessionJob new_job(job.purpose, | 556 SyncSessionJob new_job(job.purpose, |
| 568 TimeTicks::Now(), | 557 TimeTicks::Now(), |
| 569 make_linked_ptr(s), | 558 make_linked_ptr(s), |
| 570 false, | 559 false, |
| 571 job.config_params, | 560 job.config_params, |
| 572 job.from_here); | 561 job.from_here); |
| 573 wait_interval_->pending_configure_job.reset(new SyncSessionJob(new_job)); | 562 wait_interval_->pending_configure_job.reset(new SyncSessionJob(new_job)); |
| 574 } // drop the rest. | 563 } // drop the rest. |
| 575 // TODO(sync): Is it okay to drop the rest? It's weird that | 564 // TODO(sync): Is it okay to drop the rest? It's weird that |
| 576 // SaveJob() only does what it says sometimes. (See | 565 // SaveJob() only does what it says sometimes. (See |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 SDVLOG(2) << "Dropping the nudge because we are in backoff"; | 645 SDVLOG(2) << "Dropping the nudge because we are in backoff"; |
| 657 return; | 646 return; |
| 658 } | 647 } |
| 659 | 648 |
| 660 SDVLOG(2) << "Coalescing pending nudge"; | 649 SDVLOG(2) << "Coalescing pending nudge"; |
| 661 pending_nudge_->session->Coalesce(*(job.session.get())); | 650 pending_nudge_->session->Coalesce(*(job.session.get())); |
| 662 | 651 |
| 663 SDVLOG(2) << "Rescheduling pending nudge"; | 652 SDVLOG(2) << "Rescheduling pending nudge"; |
| 664 SyncSession* s = pending_nudge_->session.get(); | 653 SyncSession* s = pending_nudge_->session.get(); |
| 665 job.session.reset(new SyncSession(s->context(), s->delegate(), | 654 job.session.reset(new SyncSession(s->context(), s->delegate(), |
| 666 s->source(), s->routing_info(), s->workers())); | 655 s->source(), s->routing_info())); |
| 667 | 656 |
| 668 // Choose the start time as the earliest of the 2. | 657 // Choose the start time as the earliest of the 2. |
| 669 job.scheduled_start = std::min(job.scheduled_start, | 658 job.scheduled_start = std::min(job.scheduled_start, |
| 670 pending_nudge_->scheduled_start); | 659 pending_nudge_->scheduled_start); |
| 671 pending_nudge_.reset(); | 660 pending_nudge_.reset(); |
| 672 } | 661 } |
| 673 | 662 |
| 674 // TODO(zea): Consider adding separate throttling/backoff for datatype | 663 // TODO(zea): Consider adding separate throttling/backoff for datatype |
| 675 // refresh requests. | 664 // refresh requests. |
| 676 ScheduleSyncSessionJob(job); | 665 ScheduleSyncSessionJob(job); |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 973 | 962 |
| 974 // This will reset the had_nudge variable as well. | 963 // This will reset the had_nudge variable as well. |
| 975 wait_interval_.reset(new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, | 964 wait_interval_.reset(new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, |
| 976 length)); | 965 length)); |
| 977 if (old_job.purpose == SyncSessionJob::CONFIGURATION) { | 966 if (old_job.purpose == SyncSessionJob::CONFIGURATION) { |
| 978 SDVLOG(2) << "Configuration did not succeed, scheduling retry."; | 967 SDVLOG(2) << "Configuration did not succeed, scheduling retry."; |
| 979 // Config params should always get set. | 968 // Config params should always get set. |
| 980 DCHECK(!old_job.config_params.ready_task.is_null()); | 969 DCHECK(!old_job.config_params.ready_task.is_null()); |
| 981 SyncSession* old = old_job.session.get(); | 970 SyncSession* old = old_job.session.get(); |
| 982 SyncSession* s(new SyncSession(session_context_, this, | 971 SyncSession* s(new SyncSession(session_context_, this, |
| 983 old->source(), old->routing_info(), old->workers())); | 972 old->source(), old->routing_info())); |
| 984 SyncSessionJob job(old_job.purpose, TimeTicks::Now() + length, | 973 SyncSessionJob job(old_job.purpose, TimeTicks::Now() + length, |
| 985 make_linked_ptr(s), false, old_job.config_params, | 974 make_linked_ptr(s), false, old_job.config_params, |
| 986 FROM_HERE); | 975 FROM_HERE); |
| 987 wait_interval_->pending_configure_job.reset(new SyncSessionJob(job)); | 976 wait_interval_->pending_configure_job.reset(new SyncSessionJob(job)); |
| 988 } else { | 977 } else { |
| 989 // We are not in configuration mode. So wait_interval's pending job | 978 // We are not in configuration mode. So wait_interval's pending job |
| 990 // should be null. | 979 // should be null. |
| 991 DCHECK(wait_interval_->pending_configure_job.get() == NULL); | 980 DCHECK(wait_interval_->pending_configure_job.get() == NULL); |
| 992 | 981 |
| 993 // TODO(lipalani) - handle clear user data. | 982 // TODO(lipalani) - handle clear user data. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1055 } | 1044 } |
| 1056 | 1045 |
| 1057 SyncSession* SyncSchedulerImpl::CreateSyncSession( | 1046 SyncSession* SyncSchedulerImpl::CreateSyncSession( |
| 1058 const SyncSourceInfo& source) { | 1047 const SyncSourceInfo& source) { |
| 1059 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1048 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1060 DVLOG(2) << "Creating sync session with routes " | 1049 DVLOG(2) << "Creating sync session with routes " |
| 1061 << ModelSafeRoutingInfoToString(session_context_->routing_info()); | 1050 << ModelSafeRoutingInfoToString(session_context_->routing_info()); |
| 1062 | 1051 |
| 1063 SyncSourceInfo info(source); | 1052 SyncSourceInfo info(source); |
| 1064 SyncSession* session(new SyncSession(session_context_, this, info, | 1053 SyncSession* session(new SyncSession(session_context_, this, info, |
| 1065 session_context_->routing_info(), session_context_->workers())); | 1054 session_context_->routing_info())); |
| 1066 | 1055 |
| 1067 return session; | 1056 return session; |
| 1068 } | 1057 } |
| 1069 | 1058 |
| 1070 void SyncSchedulerImpl::PollTimerCallback() { | 1059 void SyncSchedulerImpl::PollTimerCallback() { |
| 1071 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1060 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1072 ModelSafeRoutingInfo r; | 1061 ModelSafeRoutingInfo r; |
| 1073 ModelTypeStateMap type_state_map = | 1062 ModelTypeStateMap type_state_map = |
| 1074 ModelSafeRoutingInfoToStateMap(r, std::string()); | 1063 ModelSafeRoutingInfoToStateMap(r, std::string()); |
| 1075 SyncSourceInfo info(GetUpdatesCallerInfo::PERIODIC, type_state_map); | 1064 SyncSourceInfo info(GetUpdatesCallerInfo::PERIODIC, type_state_map); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 | 1165 |
| 1177 #undef SDVLOG_LOC | 1166 #undef SDVLOG_LOC |
| 1178 | 1167 |
| 1179 #undef SDVLOG | 1168 #undef SDVLOG |
| 1180 | 1169 |
| 1181 #undef SLOG | 1170 #undef SLOG |
| 1182 | 1171 |
| 1183 #undef ENUM_CASE | 1172 #undef ENUM_CASE |
| 1184 | 1173 |
| 1185 } // namespace syncer | 1174 } // namespace syncer |
| OLD | NEW |