Chromium Code Reviews| 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(); | |
|
pavely
2015/07/27 19:45:05
You can use RunAndReset here as well.
maniscalco
2015/07/27 20:38:12
RunAndReset isn't a perfect fit since here we need
| |
| 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 |