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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 NOTREACHED(); | 72 NOTREACHED(); |
73 return false; | 73 return false; |
74 } | 74 } |
75 } | 75 } |
76 | 76 |
77 bool IsActionableError( | 77 bool IsActionableError( |
78 const SyncProtocolError& error) { | 78 const SyncProtocolError& error) { |
79 return (error.action != UNKNOWN_ACTION); | 79 return (error.action != UNKNOWN_ACTION); |
80 } | 80 } |
81 | 81 |
| 82 void RunAndReset(base::Closure* task) { |
| 83 DCHECK(task); |
| 84 if (task->is_null()) |
| 85 return; |
| 86 task->Run(); |
| 87 task->Reset(); |
| 88 } |
| 89 |
82 } // namespace | 90 } // namespace |
83 | 91 |
84 ConfigurationParams::ConfigurationParams() | 92 ConfigurationParams::ConfigurationParams() |
85 : source(GetUpdatesCallerInfo::UNKNOWN) {} | 93 : source(GetUpdatesCallerInfo::UNKNOWN) {} |
86 ConfigurationParams::ConfigurationParams( | 94 ConfigurationParams::ConfigurationParams( |
87 const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, | 95 const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, |
88 ModelTypeSet types_to_download, | 96 ModelTypeSet types_to_download, |
89 const ModelSafeRoutingInfo& routing_info, | 97 const ModelSafeRoutingInfo& routing_info, |
90 const base::Closure& ready_task, | 98 const base::Closure& ready_task, |
91 const base::Closure& retry_task) | 99 const base::Closure& retry_task) |
92 : source(source), | 100 : source(source), |
93 types_to_download(types_to_download), | 101 types_to_download(types_to_download), |
94 routing_info(routing_info), | 102 routing_info(routing_info), |
95 ready_task(ready_task), | 103 ready_task(ready_task), |
96 retry_task(retry_task) { | 104 retry_task(retry_task) { |
97 DCHECK(!ready_task.is_null()); | 105 DCHECK(!ready_task.is_null()); |
98 } | 106 } |
99 ConfigurationParams::~ConfigurationParams() {} | 107 ConfigurationParams::~ConfigurationParams() {} |
100 | 108 |
| 109 ClearParams::ClearParams(const base::Closure& report_success_task) |
| 110 : report_success_task(report_success_task) { |
| 111 DCHECK(!report_success_task.is_null()); |
| 112 } |
| 113 ClearParams::~ClearParams() {} |
| 114 |
101 SyncSchedulerImpl::WaitInterval::WaitInterval() | 115 SyncSchedulerImpl::WaitInterval::WaitInterval() |
102 : mode(UNKNOWN) {} | 116 : mode(UNKNOWN) {} |
103 | 117 |
104 SyncSchedulerImpl::WaitInterval::WaitInterval(Mode mode, TimeDelta length) | 118 SyncSchedulerImpl::WaitInterval::WaitInterval(Mode mode, TimeDelta length) |
105 : mode(mode), length(length) {} | 119 : mode(mode), length(length) {} |
106 | 120 |
107 SyncSchedulerImpl::WaitInterval::~WaitInterval() {} | 121 SyncSchedulerImpl::WaitInterval::~WaitInterval() {} |
108 | 122 |
109 #define ENUM_CASE(x) case x: return #x; break; | 123 #define ENUM_CASE(x) case x: return #x; break; |
110 | 124 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 thread_name = "<Main thread>"; | 225 thread_name = "<Main thread>"; |
212 SDVLOG(2) << "Start called from thread " | 226 SDVLOG(2) << "Start called from thread " |
213 << thread_name << " with mode " << GetModeString(mode); | 227 << thread_name << " with mode " << GetModeString(mode); |
214 if (!started_) { | 228 if (!started_) { |
215 started_ = true; | 229 started_ = true; |
216 SendInitialSnapshot(); | 230 SendInitialSnapshot(); |
217 } | 231 } |
218 | 232 |
219 DCHECK(!session_context_->account_name().empty()); | 233 DCHECK(!session_context_->account_name().empty()); |
220 DCHECK(syncer_.get()); | 234 DCHECK(syncer_.get()); |
| 235 |
| 236 if (mode == CLEAR_SERVER_DATA_MODE) { |
| 237 DCHECK_EQ(mode_, CONFIGURATION_MODE); |
| 238 } |
221 Mode old_mode = mode_; | 239 Mode old_mode = mode_; |
222 mode_ = mode; | 240 mode_ = mode; |
223 // Only adjust the poll reset time if it was valid and in the past. | 241 // Only adjust the poll reset time if it was valid and in the past. |
224 if (!last_poll_time.is_null() && last_poll_time < base::Time::Now()) { | 242 if (!last_poll_time.is_null() && last_poll_time < base::Time::Now()) { |
225 // Convert from base::Time to base::TimeTicks. The reason we use Time | 243 // Convert from base::Time to base::TimeTicks. The reason we use Time |
226 // for persisting is that TimeTicks can stop making forward progress when | 244 // for persisting is that TimeTicks can stop making forward progress when |
227 // the machine is suspended. This implies that on resume the client might | 245 // the machine is suspended. This implies that on resume the client might |
228 // actually have miss the real poll, unless the client is restarted. Fixing | 246 // actually have miss the real poll, unless the client is restarted. Fixing |
229 // that would require using an AlarmTimer though, which is only supported | 247 // that would require using an AlarmTimer though, which is only supported |
230 // on certain platforms. | 248 // on certain platforms. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 // Only reconfigure if we have types to download. | 324 // Only reconfigure if we have types to download. |
307 if (!params.types_to_download.Empty()) { | 325 if (!params.types_to_download.Empty()) { |
308 pending_configure_params_.reset(new ConfigurationParams(params)); | 326 pending_configure_params_.reset(new ConfigurationParams(params)); |
309 TrySyncSessionJob(); | 327 TrySyncSessionJob(); |
310 } else { | 328 } else { |
311 SDVLOG(2) << "No change in routing info, calling ready task directly."; | 329 SDVLOG(2) << "No change in routing info, calling ready task directly."; |
312 params.ready_task.Run(); | 330 params.ready_task.Run(); |
313 } | 331 } |
314 } | 332 } |
315 | 333 |
| 334 void SyncSchedulerImpl::ScheduleClearServerData(const ClearParams& params) { |
| 335 DCHECK(CalledOnValidThread()); |
| 336 DCHECK_EQ(CLEAR_SERVER_DATA_MODE, mode_); |
| 337 DCHECK(!pending_configure_params_); |
| 338 DCHECK(!params.report_success_task.is_null()); |
| 339 CHECK(started_) << "Scheduler must be running to clear."; |
| 340 pending_clear_params_.reset(new ClearParams(params)); |
| 341 TrySyncSessionJob(); |
| 342 } |
| 343 |
316 bool SyncSchedulerImpl::CanRunJobNow(JobPriority priority) { | 344 bool SyncSchedulerImpl::CanRunJobNow(JobPriority priority) { |
317 DCHECK(CalledOnValidThread()); | 345 DCHECK(CalledOnValidThread()); |
318 if (IsCurrentlyThrottled()) { | 346 if (IsCurrentlyThrottled()) { |
319 SDVLOG(1) << "Unable to run a job because we're throttled."; | 347 SDVLOG(1) << "Unable to run a job because we're throttled."; |
320 return false; | 348 return false; |
321 } | 349 } |
322 | 350 |
323 if (IsBackingOff() && priority != CANARY_PRIORITY) { | 351 if (IsBackingOff() && priority != CANARY_PRIORITY) { |
324 SDVLOG(1) << "Unable to run a job because we're backing off."; | 352 SDVLOG(1) << "Unable to run a job because we're backing off."; |
325 return false; | 353 return false; |
(...skipping 14 matching lines...) Expand all Loading... |
340 SDVLOG(1) << "Unable to run a nudge job right now"; | 368 SDVLOG(1) << "Unable to run a nudge job right now"; |
341 return false; | 369 return false; |
342 } | 370 } |
343 | 371 |
344 const ModelTypeSet enabled_types = session_context_->GetEnabledTypes(); | 372 const ModelTypeSet enabled_types = session_context_->GetEnabledTypes(); |
345 if (nudge_tracker_.GetThrottledTypes().HasAll(enabled_types)) { | 373 if (nudge_tracker_.GetThrottledTypes().HasAll(enabled_types)) { |
346 SDVLOG(1) << "Not running a nudge because we're fully type throttled."; | 374 SDVLOG(1) << "Not running a nudge because we're fully type throttled."; |
347 return false; | 375 return false; |
348 } | 376 } |
349 | 377 |
350 if (mode_ == CONFIGURATION_MODE) { | 378 if (mode_ != NORMAL_MODE) { |
351 SDVLOG(1) << "Not running nudge because we're in configuration mode."; | 379 SDVLOG(1) << "Not running nudge because we're not in normal mode."; |
352 return false; | 380 return false; |
353 } | 381 } |
354 | 382 |
355 return true; | 383 return true; |
356 } | 384 } |
357 | 385 |
358 void SyncSchedulerImpl::ScheduleLocalNudge( | 386 void SyncSchedulerImpl::ScheduleLocalNudge( |
359 ModelTypeSet types, | 387 ModelTypeSet types, |
360 const tracked_objects::Location& nudge_location) { | 388 const tracked_objects::Location& nudge_location) { |
361 DCHECK(CalledOnValidThread()); | 389 DCHECK(CalledOnValidThread()); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 pending_wakeup_timer_.Start( | 471 pending_wakeup_timer_.Start( |
444 nudge_location, | 472 nudge_location, |
445 delay, | 473 delay, |
446 base::Bind(&SyncSchedulerImpl::PerformDelayedNudge, | 474 base::Bind(&SyncSchedulerImpl::PerformDelayedNudge, |
447 weak_ptr_factory_.GetWeakPtr())); | 475 weak_ptr_factory_.GetWeakPtr())); |
448 } | 476 } |
449 | 477 |
450 const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) { | 478 const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) { |
451 switch (mode) { | 479 switch (mode) { |
452 ENUM_CASE(CONFIGURATION_MODE); | 480 ENUM_CASE(CONFIGURATION_MODE); |
| 481 ENUM_CASE(CLEAR_SERVER_DATA_MODE); |
453 ENUM_CASE(NORMAL_MODE); | 482 ENUM_CASE(NORMAL_MODE); |
454 } | 483 } |
455 return ""; | 484 return ""; |
456 } | 485 } |
457 | 486 |
458 void SyncSchedulerImpl::SetDefaultNudgeDelay(base::TimeDelta delay_ms) { | 487 void SyncSchedulerImpl::SetDefaultNudgeDelay(base::TimeDelta delay_ms) { |
459 DCHECK(CalledOnValidThread()); | 488 DCHECK(CalledOnValidThread()); |
460 nudge_tracker_.SetDefaultNudgeDelay(delay_ms); | 489 nudge_tracker_.SetDefaultNudgeDelay(delay_ms); |
461 } | 490 } |
462 | 491 |
(...skipping 26 matching lines...) Expand all Loading... |
489 } | 518 } |
490 } | 519 } |
491 | 520 |
492 void SyncSchedulerImpl::DoConfigurationSyncSessionJob(JobPriority priority) { | 521 void SyncSchedulerImpl::DoConfigurationSyncSessionJob(JobPriority priority) { |
493 DCHECK(CalledOnValidThread()); | 522 DCHECK(CalledOnValidThread()); |
494 DCHECK_EQ(mode_, CONFIGURATION_MODE); | 523 DCHECK_EQ(mode_, CONFIGURATION_MODE); |
495 DCHECK(pending_configure_params_ != NULL); | 524 DCHECK(pending_configure_params_ != NULL); |
496 | 525 |
497 if (!CanRunJobNow(priority)) { | 526 if (!CanRunJobNow(priority)) { |
498 SDVLOG(2) << "Unable to run configure job right now."; | 527 SDVLOG(2) << "Unable to run configure job right now."; |
499 if (!pending_configure_params_->retry_task.is_null()) { | 528 RunAndReset(&pending_configure_params_->retry_task); |
500 pending_configure_params_->retry_task.Run(); | |
501 pending_configure_params_->retry_task.Reset(); | |
502 } | |
503 return; | 529 return; |
504 } | 530 } |
505 | 531 |
506 SDVLOG(2) << "Will run configure SyncShare with types " | 532 SDVLOG(2) << "Will run configure SyncShare with types " |
507 << ModelTypeSetToString(session_context_->GetEnabledTypes()); | 533 << ModelTypeSetToString(session_context_->GetEnabledTypes()); |
508 scoped_ptr<SyncSession> session(SyncSession::Build(session_context_, this)); | 534 scoped_ptr<SyncSession> session(SyncSession::Build(session_context_, this)); |
509 bool success = syncer_->ConfigureSyncShare( | 535 bool success = syncer_->ConfigureSyncShare( |
510 pending_configure_params_->types_to_download, | 536 pending_configure_params_->types_to_download, |
511 pending_configure_params_->source, | 537 pending_configure_params_->source, |
512 session.get()); | 538 session.get()); |
513 | 539 |
514 if (success) { | 540 if (success) { |
515 SDVLOG(2) << "Configure succeeded."; | 541 SDVLOG(2) << "Configure succeeded."; |
516 pending_configure_params_->ready_task.Run(); | 542 pending_configure_params_->ready_task.Run(); |
517 pending_configure_params_.reset(); | 543 pending_configure_params_.reset(); |
518 HandleSuccess(); | 544 HandleSuccess(); |
519 } else { | 545 } else { |
520 HandleFailure(session->status_controller().model_neutral_state()); | 546 HandleFailure(session->status_controller().model_neutral_state()); |
521 // Sync cycle might receive response from server that causes scheduler to | 547 // Sync cycle might receive response from server that causes scheduler to |
522 // stop and draws pending_configure_params_ invalid. | 548 // stop and draws pending_configure_params_ invalid. |
523 if (started_ && !pending_configure_params_->retry_task.is_null()) { | 549 if (started_) |
524 pending_configure_params_->retry_task.Run(); | 550 RunAndReset(&pending_configure_params_->retry_task); |
525 pending_configure_params_->retry_task.Reset(); | |
526 } | |
527 } | 551 } |
528 } | 552 } |
529 | 553 |
| 554 void SyncSchedulerImpl::DoClearServerDataSyncSessionJob(JobPriority priority) { |
| 555 DCHECK(CalledOnValidThread()); |
| 556 DCHECK_EQ(mode_, CLEAR_SERVER_DATA_MODE); |
| 557 |
| 558 if (!CanRunJobNow(priority)) { |
| 559 SDVLOG(2) << "Unable to run clear server data job right now."; |
| 560 RunAndReset(&pending_configure_params_->retry_task); |
| 561 return; |
| 562 } |
| 563 |
| 564 scoped_ptr<SyncSession> session(SyncSession::Build(session_context_, this)); |
| 565 const bool success = syncer_->PostClearServerData(session.get()); |
| 566 if (!success) { |
| 567 HandleFailure(session->status_controller().model_neutral_state()); |
| 568 return; |
| 569 } |
| 570 |
| 571 SDVLOG(2) << "Clear succeeded."; |
| 572 pending_clear_params_->report_success_task.Run(); |
| 573 pending_clear_params_.reset(); |
| 574 HandleSuccess(); |
| 575 } |
| 576 |
530 void SyncSchedulerImpl::HandleSuccess() { | 577 void SyncSchedulerImpl::HandleSuccess() { |
531 // If we're here, then we successfully reached the server. End all backoff. | 578 // If we're here, then we successfully reached the server. End all backoff. |
532 wait_interval_.reset(); | 579 wait_interval_.reset(); |
533 NotifyRetryTime(base::Time()); | 580 NotifyRetryTime(base::Time()); |
534 } | 581 } |
535 | 582 |
536 void SyncSchedulerImpl::HandleFailure( | 583 void SyncSchedulerImpl::HandleFailure( |
537 const sessions::ModelNeutralState& model_neutral_state) { | 584 const sessions::ModelNeutralState& model_neutral_state) { |
538 if (IsCurrentlyThrottled()) { | 585 if (IsCurrentlyThrottled()) { |
539 SDVLOG(2) << "Was throttled during previous sync cycle."; | 586 SDVLOG(2) << "Was throttled during previous sync cycle."; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
666 DCHECK(CalledOnValidThread()); | 713 DCHECK(CalledOnValidThread()); |
667 SDVLOG(2) << "Stop called"; | 714 SDVLOG(2) << "Stop called"; |
668 | 715 |
669 // Kill any in-flight method calls. | 716 // Kill any in-flight method calls. |
670 weak_ptr_factory_.InvalidateWeakPtrs(); | 717 weak_ptr_factory_.InvalidateWeakPtrs(); |
671 wait_interval_.reset(); | 718 wait_interval_.reset(); |
672 NotifyRetryTime(base::Time()); | 719 NotifyRetryTime(base::Time()); |
673 poll_timer_.Stop(); | 720 poll_timer_.Stop(); |
674 pending_wakeup_timer_.Stop(); | 721 pending_wakeup_timer_.Stop(); |
675 pending_configure_params_.reset(); | 722 pending_configure_params_.reset(); |
| 723 pending_clear_params_.reset(); |
676 if (started_) | 724 if (started_) |
677 started_ = false; | 725 started_ = false; |
678 } | 726 } |
679 | 727 |
680 // This is the only place where we invoke DoSyncSessionJob with canary | 728 // This is the only place where we invoke DoSyncSessionJob with canary |
681 // privileges. Everyone else should use NORMAL_PRIORITY. | 729 // privileges. Everyone else should use NORMAL_PRIORITY. |
682 void SyncSchedulerImpl::TryCanaryJob() { | 730 void SyncSchedulerImpl::TryCanaryJob() { |
683 next_sync_session_job_priority_ = CANARY_PRIORITY; | 731 next_sync_session_job_priority_ = CANARY_PRIORITY; |
684 SDVLOG(2) << "Attempting canary job"; | 732 SDVLOG(2) << "Attempting canary job"; |
685 TrySyncSessionJob(); | 733 TrySyncSessionJob(); |
(...skipping 12 matching lines...) Expand all Loading... |
698 next_sync_session_job_priority_ = NORMAL_PRIORITY; | 746 next_sync_session_job_priority_ = NORMAL_PRIORITY; |
699 | 747 |
700 nudge_tracker_.SetSyncCycleStartTime(base::TimeTicks::Now()); | 748 nudge_tracker_.SetSyncCycleStartTime(base::TimeTicks::Now()); |
701 | 749 |
702 DCHECK(CalledOnValidThread()); | 750 DCHECK(CalledOnValidThread()); |
703 if (mode_ == CONFIGURATION_MODE) { | 751 if (mode_ == CONFIGURATION_MODE) { |
704 if (pending_configure_params_) { | 752 if (pending_configure_params_) { |
705 SDVLOG(2) << "Found pending configure job"; | 753 SDVLOG(2) << "Found pending configure job"; |
706 DoConfigurationSyncSessionJob(priority); | 754 DoConfigurationSyncSessionJob(priority); |
707 } | 755 } |
| 756 } else if (mode_ == CLEAR_SERVER_DATA_MODE) { |
| 757 if (pending_clear_params_) { |
| 758 DoClearServerDataSyncSessionJob(priority); |
| 759 } |
708 } else if (CanRunNudgeJobNow(priority)) { | 760 } else if (CanRunNudgeJobNow(priority)) { |
709 if (nudge_tracker_.IsSyncRequired()) { | 761 if (nudge_tracker_.IsSyncRequired()) { |
710 SDVLOG(2) << "Found pending nudge job"; | 762 SDVLOG(2) << "Found pending nudge job"; |
711 DoNudgeSyncSessionJob(priority); | 763 DoNudgeSyncSessionJob(priority); |
712 } else if (((base::TimeTicks::Now() - last_poll_reset_) >= | 764 } else if (((base::TimeTicks::Now() - last_poll_reset_) >= |
713 GetPollInterval())) { | 765 GetPollInterval())) { |
714 SDVLOG(2) << "Found pending poll"; | 766 SDVLOG(2) << "Found pending poll"; |
715 DoPollSyncSessionJob(); | 767 DoPollSyncSessionJob(); |
716 } | 768 } |
717 } else { | 769 } else { |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 | 978 |
927 #undef SDVLOG_LOC | 979 #undef SDVLOG_LOC |
928 | 980 |
929 #undef SDVLOG | 981 #undef SDVLOG |
930 | 982 |
931 #undef SLOG | 983 #undef SLOG |
932 | 984 |
933 #undef ENUM_CASE | 985 #undef ENUM_CASE |
934 | 986 |
935 } // namespace syncer | 987 } // namespace syncer |
OLD | NEW |