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 "components/sync/engine_impl/sync_scheduler_impl.h" | 5 #include "components/sync/engine_impl/sync_scheduler_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 } | 81 } |
| 82 | 82 |
| 83 void RunAndReset(base::Closure* task) { | 83 void RunAndReset(base::Closure* task) { |
| 84 DCHECK(task); | 84 DCHECK(task); |
| 85 if (task->is_null()) | 85 if (task->is_null()) |
| 86 return; | 86 return; |
| 87 task->Run(); | 87 task->Run(); |
| 88 task->Reset(); | 88 task->Reset(); |
| 89 } | 89 } |
| 90 | 90 |
| 91 #define ENUM_CASE(x) \ | |
| 92 case x: \ | |
| 93 return #x; \ | |
| 94 break; | |
| 95 | |
| 91 } // namespace | 96 } // namespace |
| 92 | 97 |
| 93 ConfigurationParams::ConfigurationParams() | 98 ConfigurationParams::ConfigurationParams() |
| 94 : source(GetUpdatesCallerInfo::UNKNOWN) {} | 99 : source(GetUpdatesCallerInfo::UNKNOWN) {} |
| 95 ConfigurationParams::ConfigurationParams( | 100 ConfigurationParams::ConfigurationParams( |
| 96 const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, | 101 const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, |
| 97 ModelTypeSet types_to_download, | 102 ModelTypeSet types_to_download, |
| 98 const ModelSafeRoutingInfo& routing_info, | 103 const ModelSafeRoutingInfo& routing_info, |
| 99 const base::Closure& ready_task, | 104 const base::Closure& ready_task, |
| 100 const base::Closure& retry_task) | 105 const base::Closure& retry_task) |
| 101 : source(source), | 106 : source(source), |
| 102 types_to_download(types_to_download), | 107 types_to_download(types_to_download), |
| 103 routing_info(routing_info), | 108 routing_info(routing_info), |
| 104 ready_task(ready_task), | 109 ready_task(ready_task), |
| 105 retry_task(retry_task) { | 110 retry_task(retry_task) { |
| 106 DCHECK(!ready_task.is_null()); | 111 DCHECK(!ready_task.is_null()); |
| 107 } | 112 } |
| 108 ConfigurationParams::ConfigurationParams(const ConfigurationParams& other) = | 113 ConfigurationParams::ConfigurationParams(const ConfigurationParams& other) = |
| 109 default; | 114 default; |
| 110 ConfigurationParams::~ConfigurationParams() {} | 115 ConfigurationParams::~ConfigurationParams() {} |
| 111 | 116 |
| 112 ClearParams::ClearParams(const base::Closure& report_success_task) | 117 ClearParams::ClearParams(const base::Closure& report_success_task) |
| 113 : report_success_task(report_success_task) { | 118 : report_success_task(report_success_task) { |
| 114 DCHECK(!report_success_task.is_null()); | 119 DCHECK(!report_success_task.is_null()); |
| 115 } | 120 } |
| 116 ClearParams::ClearParams(const ClearParams& other) = default; | 121 ClearParams::ClearParams(const ClearParams& other) = default; |
| 117 ClearParams::~ClearParams() {} | 122 ClearParams::~ClearParams() {} |
| 118 | 123 |
| 119 SyncSchedulerImpl::WaitInterval::WaitInterval() : mode(UNKNOWN) {} | |
| 120 | |
| 121 SyncSchedulerImpl::WaitInterval::WaitInterval(Mode mode, TimeDelta length) | |
| 122 : mode(mode), length(length) {} | |
| 123 | |
| 124 SyncSchedulerImpl::WaitInterval::~WaitInterval() {} | |
| 125 | |
| 126 #define ENUM_CASE(x) \ | |
| 127 case x: \ | |
| 128 return #x; \ | |
| 129 break; | |
| 130 | |
| 131 const char* SyncSchedulerImpl::WaitInterval::GetModeString(Mode mode) { | |
| 132 switch (mode) { | |
| 133 ENUM_CASE(UNKNOWN); | |
| 134 ENUM_CASE(EXPONENTIAL_BACKOFF); | |
| 135 ENUM_CASE(THROTTLED); | |
| 136 } | |
| 137 NOTREACHED(); | |
| 138 return ""; | |
| 139 } | |
| 140 | |
| 141 GetUpdatesCallerInfo::GetUpdatesSource GetUpdatesFromNudgeSource( | 124 GetUpdatesCallerInfo::GetUpdatesSource GetUpdatesFromNudgeSource( |
| 142 NudgeSource source) { | 125 NudgeSource source) { |
| 143 switch (source) { | 126 switch (source) { |
| 144 case NUDGE_SOURCE_NOTIFICATION: | 127 case NUDGE_SOURCE_NOTIFICATION: |
| 145 return GetUpdatesCallerInfo::NOTIFICATION; | 128 return GetUpdatesCallerInfo::NOTIFICATION; |
| 146 case NUDGE_SOURCE_LOCAL: | 129 case NUDGE_SOURCE_LOCAL: |
| 147 return GetUpdatesCallerInfo::LOCAL; | 130 return GetUpdatesCallerInfo::LOCAL; |
| 148 case NUDGE_SOURCE_LOCAL_REFRESH: | 131 case NUDGE_SOURCE_LOCAL_REFRESH: |
| 149 return GetUpdatesCallerInfo::DATATYPE_REFRESH; | 132 return GetUpdatesCallerInfo::DATATYPE_REFRESH; |
| 150 case NUDGE_SOURCE_UNKNOWN: | 133 case NUDGE_SOURCE_UNKNOWN: |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 244 Mode old_mode = mode_; | 227 Mode old_mode = mode_; |
| 245 mode_ = mode; | 228 mode_ = mode; |
| 246 // Only adjust the poll reset time if it was valid and in the past. | 229 // Only adjust the poll reset time if it was valid and in the past. |
| 247 if (!last_poll_time.is_null() && last_poll_time < base::Time::Now()) { | 230 if (!last_poll_time.is_null() && last_poll_time < base::Time::Now()) { |
| 248 // Convert from base::Time to base::TimeTicks. The reason we use Time | 231 // Convert from base::Time to base::TimeTicks. The reason we use Time |
| 249 // for persisting is that TimeTicks can stop making forward progress when | 232 // for persisting is that TimeTicks can stop making forward progress when |
| 250 // the machine is suspended. This implies that on resume the client might | 233 // the machine is suspended. This implies that on resume the client might |
| 251 // actually have miss the real poll, unless the client is restarted. Fixing | 234 // actually have miss the real poll, unless the client is restarted. Fixing |
| 252 // that would require using an AlarmTimer though, which is only supported | 235 // that would require using an AlarmTimer though, which is only supported |
| 253 // on certain platforms. | 236 // on certain platforms. |
| 254 last_poll_reset_ = | 237 last_poll_reset_ = TimeTicks::Now() - (base::Time::Now() - last_poll_time); |
| 255 base::TimeTicks::Now() - (base::Time::Now() - last_poll_time); | |
| 256 } | 238 } |
| 257 | 239 |
| 258 if (old_mode != mode_ && mode_ == NORMAL_MODE) { | 240 if (old_mode != mode_ && mode_ == NORMAL_MODE) { |
| 259 // We just got back to normal mode. Let's try to run the work that was | 241 // We just got back to normal mode. Let's try to run the work that was |
| 260 // queued up while we were configuring. | 242 // queued up while we were configuring. |
| 261 | 243 |
| 262 AdjustPolling(UPDATE_INTERVAL); // Will kick start poll timer if needed. | 244 AdjustPolling(UPDATE_INTERVAL); // Will kick start poll timer if needed. |
| 263 | 245 |
| 264 // Update our current time before checking IsRetryRequired(). | 246 // Update our current time before checking IsRetryRequired(). |
| 265 nudge_tracker_.SetSyncCycleStartTime(base::TimeTicks::Now()); | 247 nudge_tracker_.SetSyncCycleStartTime(TimeTicks::Now()); |
| 266 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) { | 248 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) { |
| 267 TrySyncCycleJob(); | 249 TrySyncCycleJob(); |
| 268 } | 250 } |
| 269 } | 251 } |
| 270 } | 252 } |
| 271 | 253 |
| 272 ModelTypeSet SyncSchedulerImpl::GetEnabledAndUnthrottledTypes() { | 254 ModelTypeSet SyncSchedulerImpl::GetEnabledAndUnblockedTypes() { |
| 273 ModelTypeSet enabled_types = cycle_context_->GetEnabledTypes(); | 255 ModelTypeSet enabled_types = cycle_context_->GetEnabledTypes(); |
| 274 ModelTypeSet enabled_protocol_types = | 256 ModelTypeSet enabled_protocol_types = |
| 275 Intersection(ProtocolTypes(), enabled_types); | 257 Intersection(ProtocolTypes(), enabled_types); |
| 276 ModelTypeSet throttled_types = nudge_tracker_.GetThrottledTypes(); | 258 ModelTypeSet throttled_types = nudge_tracker_.GetThrottledTypes(); |
| 277 return Difference(enabled_protocol_types, throttled_types); | 259 ModelTypeSet backed_off_types = nudge_tracker_.GetBackedOffTypes(); |
| 260 return Difference(enabled_protocol_types, | |
| 261 Union(throttled_types, backed_off_types)); | |
| 278 } | 262 } |
| 279 | 263 |
| 280 void SyncSchedulerImpl::SendInitialSnapshot() { | 264 void SyncSchedulerImpl::SendInitialSnapshot() { |
| 281 DCHECK(CalledOnValidThread()); | 265 DCHECK(CalledOnValidThread()); |
| 282 std::unique_ptr<SyncCycle> dummy(SyncCycle::Build(cycle_context_, this)); | 266 std::unique_ptr<SyncCycle> dummy(SyncCycle::Build(cycle_context_, this)); |
| 283 SyncCycleEvent event(SyncCycleEvent::STATUS_CHANGED); | 267 SyncCycleEvent event(SyncCycleEvent::STATUS_CHANGED); |
| 284 event.snapshot = dummy->TakeSnapshot(); | 268 event.snapshot = dummy->TakeSnapshot(); |
| 285 for (auto& observer : *cycle_context_->listeners()) | 269 for (auto& observer : *cycle_context_->listeners()) |
| 286 observer.OnSyncCycleEvent(event); | 270 observer.OnSyncCycleEvent(event); |
| 287 } | 271 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 | 371 |
| 388 void SyncSchedulerImpl::ScheduleLocalNudge( | 372 void SyncSchedulerImpl::ScheduleLocalNudge( |
| 389 ModelTypeSet types, | 373 ModelTypeSet types, |
| 390 const tracked_objects::Location& nudge_location) { | 374 const tracked_objects::Location& nudge_location) { |
| 391 DCHECK(CalledOnValidThread()); | 375 DCHECK(CalledOnValidThread()); |
| 392 DCHECK(!types.Empty()); | 376 DCHECK(!types.Empty()); |
| 393 | 377 |
| 394 SDVLOG_LOC(nudge_location, 2) << "Scheduling sync because of local change to " | 378 SDVLOG_LOC(nudge_location, 2) << "Scheduling sync because of local change to " |
| 395 << ModelTypeSetToString(types); | 379 << ModelTypeSetToString(types); |
| 396 UpdateNudgeTimeRecords(types); | 380 UpdateNudgeTimeRecords(types); |
| 397 base::TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(types); | 381 TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(types); |
| 398 ScheduleNudgeImpl(nudge_delay, nudge_location); | 382 ScheduleNudgeImpl(nudge_delay, nudge_location); |
| 399 } | 383 } |
| 400 | 384 |
| 401 void SyncSchedulerImpl::ScheduleLocalRefreshRequest( | 385 void SyncSchedulerImpl::ScheduleLocalRefreshRequest( |
| 402 ModelTypeSet types, | 386 ModelTypeSet types, |
| 403 const tracked_objects::Location& nudge_location) { | 387 const tracked_objects::Location& nudge_location) { |
| 404 DCHECK(CalledOnValidThread()); | 388 DCHECK(CalledOnValidThread()); |
| 405 DCHECK(!types.Empty()); | 389 DCHECK(!types.Empty()); |
| 406 | 390 |
| 407 SDVLOG_LOC(nudge_location, 2) | 391 SDVLOG_LOC(nudge_location, 2) |
| 408 << "Scheduling sync because of local refresh request for " | 392 << "Scheduling sync because of local refresh request for " |
| 409 << ModelTypeSetToString(types); | 393 << ModelTypeSetToString(types); |
| 410 base::TimeDelta nudge_delay = nudge_tracker_.RecordLocalRefreshRequest(types); | 394 TimeDelta nudge_delay = nudge_tracker_.RecordLocalRefreshRequest(types); |
| 411 ScheduleNudgeImpl(nudge_delay, nudge_location); | 395 ScheduleNudgeImpl(nudge_delay, nudge_location); |
| 412 } | 396 } |
| 413 | 397 |
| 414 void SyncSchedulerImpl::ScheduleInvalidationNudge( | 398 void SyncSchedulerImpl::ScheduleInvalidationNudge( |
| 415 ModelType model_type, | 399 ModelType model_type, |
| 416 std::unique_ptr<InvalidationInterface> invalidation, | 400 std::unique_ptr<InvalidationInterface> invalidation, |
| 417 const tracked_objects::Location& nudge_location) { | 401 const tracked_objects::Location& nudge_location) { |
| 418 DCHECK(CalledOnValidThread()); | 402 DCHECK(CalledOnValidThread()); |
| 419 | 403 |
| 420 SDVLOG_LOC(nudge_location, 2) | 404 SDVLOG_LOC(nudge_location, 2) |
| 421 << "Scheduling sync because we received invalidation for " | 405 << "Scheduling sync because we received invalidation for " |
| 422 << ModelTypeToString(model_type); | 406 << ModelTypeToString(model_type); |
| 423 base::TimeDelta nudge_delay = nudge_tracker_.RecordRemoteInvalidation( | 407 TimeDelta nudge_delay = nudge_tracker_.RecordRemoteInvalidation( |
| 424 model_type, std::move(invalidation)); | 408 model_type, std::move(invalidation)); |
| 425 ScheduleNudgeImpl(nudge_delay, nudge_location); | 409 ScheduleNudgeImpl(nudge_delay, nudge_location); |
| 426 } | 410 } |
| 427 | 411 |
| 428 void SyncSchedulerImpl::ScheduleInitialSyncNudge(ModelType model_type) { | 412 void SyncSchedulerImpl::ScheduleInitialSyncNudge(ModelType model_type) { |
| 429 DCHECK(CalledOnValidThread()); | 413 DCHECK(CalledOnValidThread()); |
| 430 | 414 |
| 431 SDVLOG(2) << "Scheduling non-blocking initial sync for " | 415 SDVLOG(2) << "Scheduling non-blocking initial sync for " |
| 432 << ModelTypeToString(model_type); | 416 << ModelTypeToString(model_type); |
| 433 nudge_tracker_.RecordInitialSyncRequired(model_type); | 417 nudge_tracker_.RecordInitialSyncRequired(model_type); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 448 return; | 432 return; |
| 449 } | 433 } |
| 450 | 434 |
| 451 SDVLOG_LOC(nudge_location, 2) << "In ScheduleNudgeImpl with delay " | 435 SDVLOG_LOC(nudge_location, 2) << "In ScheduleNudgeImpl with delay " |
| 452 << delay.InMilliseconds() << " ms"; | 436 << delay.InMilliseconds() << " ms"; |
| 453 | 437 |
| 454 if (!CanRunNudgeJobNow(NORMAL_PRIORITY)) | 438 if (!CanRunNudgeJobNow(NORMAL_PRIORITY)) |
| 455 return; | 439 return; |
| 456 | 440 |
| 457 TimeTicks incoming_run_time = TimeTicks::Now() + delay; | 441 TimeTicks incoming_run_time = TimeTicks::Now() + delay; |
| 458 if (!scheduled_nudge_time_.is_null() && | 442 if (global_wakeup_timer_.IsRunning() && |
| 459 (scheduled_nudge_time_ < incoming_run_time)) { | 443 (global_wakeup_timer_.desired_run_time() < incoming_run_time)) { |
| 460 // Old job arrives sooner than this one. Don't reschedule it. | 444 // Old job arrives sooner than this one. Don't reschedule it. |
| 461 return; | 445 return; |
| 462 } | 446 } |
| 463 | 447 |
| 464 // Either there is no existing nudge in flight or the incoming nudge should be | 448 // Either there is no existing nudge in flight or the incoming nudge should be |
| 465 // made to arrive first (preempt) the existing nudge. We reschedule in either | 449 // made to arrive first (preempt) the existing nudge. We reschedule in either |
| 466 // case. | 450 // case. |
| 467 SDVLOG_LOC(nudge_location, 2) << "Scheduling a nudge with " | 451 SDVLOG_LOC(nudge_location, 2) << "Scheduling a nudge with " |
| 468 << delay.InMilliseconds() << " ms delay"; | 452 << delay.InMilliseconds() << " ms delay"; |
| 469 scheduled_nudge_time_ = incoming_run_time; | 453 global_wakeup_timer_.Start(nudge_location, delay, |
| 470 pending_wakeup_timer_.Start( | 454 base::Bind(&SyncSchedulerImpl::PerformDelayedNudge, |
| 471 nudge_location, delay, base::Bind(&SyncSchedulerImpl::PerformDelayedNudge, | |
| 472 weak_ptr_factory_.GetWeakPtr())); | 455 weak_ptr_factory_.GetWeakPtr())); |
| 473 } | 456 } |
| 474 | 457 |
| 475 const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) { | 458 const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) { |
| 476 switch (mode) { | 459 switch (mode) { |
| 477 ENUM_CASE(CONFIGURATION_MODE); | 460 ENUM_CASE(CONFIGURATION_MODE); |
| 478 ENUM_CASE(CLEAR_SERVER_DATA_MODE); | 461 ENUM_CASE(CLEAR_SERVER_DATA_MODE); |
| 479 ENUM_CASE(NORMAL_MODE); | 462 ENUM_CASE(NORMAL_MODE); |
| 480 } | 463 } |
| 481 return ""; | 464 return ""; |
| 482 } | 465 } |
| 483 | 466 |
| 484 void SyncSchedulerImpl::SetDefaultNudgeDelay(base::TimeDelta delay_ms) { | 467 void SyncSchedulerImpl::SetDefaultNudgeDelay(TimeDelta delay_ms) { |
| 485 DCHECK(CalledOnValidThread()); | 468 DCHECK(CalledOnValidThread()); |
| 486 nudge_tracker_.SetDefaultNudgeDelay(delay_ms); | 469 nudge_tracker_.SetDefaultNudgeDelay(delay_ms); |
| 487 } | 470 } |
| 488 | 471 |
| 489 void SyncSchedulerImpl::DoNudgeSyncCycleJob(JobPriority priority) { | 472 void SyncSchedulerImpl::DoNudgeSyncCycleJob(JobPriority priority) { |
| 490 DCHECK(CalledOnValidThread()); | 473 DCHECK(CalledOnValidThread()); |
| 491 DCHECK(CanRunNudgeJobNow(priority)); | 474 DCHECK(CanRunNudgeJobNow(priority)); |
| 492 | 475 |
| 493 DVLOG(2) << "Will run normal mode sync cycle with types " | 476 DVLOG(2) << "Will run normal mode sync cycle with types " |
| 494 << ModelTypeSetToString(cycle_context_->GetEnabledTypes()); | 477 << ModelTypeSetToString(cycle_context_->GetEnabledTypes()); |
| 495 std::unique_ptr<SyncCycle> cycle(SyncCycle::Build(cycle_context_, this)); | 478 std::unique_ptr<SyncCycle> cycle(SyncCycle::Build(cycle_context_, this)); |
| 496 bool success = syncer_->NormalSyncShare(GetEnabledAndUnthrottledTypes(), | 479 bool success = syncer_->NormalSyncShare(GetEnabledAndUnblockedTypes(), |
| 497 &nudge_tracker_, cycle.get()); | 480 &nudge_tracker_, cycle.get()); |
| 498 | 481 |
| 499 if (success) { | 482 if (success) { |
| 500 // That cycle took care of any outstanding work we had. | 483 // That cycle took care of any outstanding work we had. |
| 501 SDVLOG(2) << "Nudge succeeded."; | 484 SDVLOG(2) << "Nudge succeeded."; |
| 502 nudge_tracker_.RecordSuccessfulSyncCycle(); | 485 nudge_tracker_.RecordSuccessfulSyncCycle(); |
| 503 scheduled_nudge_time_ = base::TimeTicks(); | |
| 504 HandleSuccess(); | 486 HandleSuccess(); |
| 505 | 487 |
| 506 // If this was a canary, we may need to restart the poll timer (the poll | 488 // If this was a canary, we may need to restart the poll timer (the poll |
| 507 // timer may have fired while the scheduler was in an error state, ignoring | 489 // timer may have fired while the scheduler was in an error state, ignoring |
| 508 // the poll). | 490 // the poll). |
| 509 if (!poll_timer_.IsRunning()) { | 491 if (!poll_timer_.IsRunning()) { |
| 510 SDVLOG(1) << "Canary succeeded, restarting polling."; | 492 SDVLOG(1) << "Canary succeeded, restarting polling."; |
| 511 AdjustPolling(UPDATE_INTERVAL); | 493 AdjustPolling(UPDATE_INTERVAL); |
| 512 } | 494 } |
| 513 } else { | 495 } else { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 571 } | 553 } |
| 572 | 554 |
| 573 void SyncSchedulerImpl::HandleSuccess() { | 555 void SyncSchedulerImpl::HandleSuccess() { |
| 574 // If we're here, then we successfully reached the server. End all backoff. | 556 // If we're here, then we successfully reached the server. End all backoff. |
| 575 wait_interval_.reset(); | 557 wait_interval_.reset(); |
| 576 NotifyRetryTime(base::Time()); | 558 NotifyRetryTime(base::Time()); |
| 577 } | 559 } |
| 578 | 560 |
| 579 void SyncSchedulerImpl::HandleFailure( | 561 void SyncSchedulerImpl::HandleFailure( |
| 580 const ModelNeutralState& model_neutral_state) { | 562 const ModelNeutralState& model_neutral_state) { |
| 563 if (model_neutral_state.commit_result == SERVER_RETURN_PARTIAL_FAILURE) { | |
|
Nicolas Zea
2016/11/09 00:21:25
Should partial failure just count as success?
Gang Wu
2016/11/10 21:56:51
Done.
| |
| 564 // Since it is partial failure, we have handled in OnTypesThrottled or | |
| 565 // OnTypesBackedOff already. | |
| 566 return; | |
| 567 } | |
| 581 if (IsCurrentlyThrottled()) { | 568 if (IsCurrentlyThrottled()) { |
| 582 SDVLOG(2) << "Was throttled during previous sync cycle."; | 569 SDVLOG(2) << "Was throttled during previous sync cycle."; |
| 583 } else if (!IsBackingOff()) { | 570 } else if (!IsBackingOff()) { |
| 584 // Setup our backoff if this is our first such failure. | 571 // Setup our backoff if this is our first such failure. |
| 585 TimeDelta length = delay_provider_->GetDelay( | 572 TimeDelta length = delay_provider_->GetDelay( |
| 586 delay_provider_->GetInitialDelay(model_neutral_state)); | 573 delay_provider_->GetInitialDelay(model_neutral_state)); |
| 587 wait_interval_ = base::MakeUnique<WaitInterval>( | 574 wait_interval_ = base::MakeUnique<WaitInterval>( |
| 588 WaitInterval::EXPONENTIAL_BACKOFF, length); | 575 WaitInterval::EXPONENTIAL_BACKOFF, length); |
| 589 SDVLOG(2) << "Sync cycle failed. Will back off for " | 576 SDVLOG(2) << "Sync cycle failed. Will back off for " |
| 590 << wait_interval_->length.InMilliseconds() << "ms."; | 577 << wait_interval_->length.InMilliseconds() << "ms."; |
| 591 } else { | 578 } else { |
| 592 // Increase our backoff interval and schedule another retry. | 579 // Increase our backoff interval and schedule another retry. |
| 593 TimeDelta length = delay_provider_->GetDelay(wait_interval_->length); | 580 TimeDelta length = delay_provider_->GetDelay(wait_interval_->length); |
| 594 wait_interval_ = base::MakeUnique<WaitInterval>( | 581 wait_interval_ = base::MakeUnique<WaitInterval>( |
| 595 WaitInterval::EXPONENTIAL_BACKOFF, length); | 582 WaitInterval::EXPONENTIAL_BACKOFF, length); |
| 596 SDVLOG(2) << "Sync cycle failed. Will back off for " | 583 SDVLOG(2) << "Sync cycle failed. Will back off for " |
| 597 << wait_interval_->length.InMilliseconds() << "ms."; | 584 << wait_interval_->length.InMilliseconds() << "ms."; |
| 598 } | 585 } |
| 599 RestartWaiting(); | 586 RestartWaiting(); |
| 600 } | 587 } |
| 601 | 588 |
| 602 void SyncSchedulerImpl::DoPollSyncCycleJob() { | 589 void SyncSchedulerImpl::DoPollSyncCycleJob() { |
| 603 SDVLOG(2) << "Polling with types " | 590 SDVLOG(2) << "Polling with types " |
| 604 << ModelTypeSetToString(GetEnabledAndUnthrottledTypes()); | 591 << ModelTypeSetToString(GetEnabledAndUnblockedTypes()); |
| 605 std::unique_ptr<SyncCycle> cycle(SyncCycle::Build(cycle_context_, this)); | 592 std::unique_ptr<SyncCycle> cycle(SyncCycle::Build(cycle_context_, this)); |
| 606 bool success = | 593 bool success = |
| 607 syncer_->PollSyncShare(GetEnabledAndUnthrottledTypes(), cycle.get()); | 594 syncer_->PollSyncShare(GetEnabledAndUnblockedTypes(), cycle.get()); |
| 608 | 595 |
| 609 // Only restart the timer if the poll succeeded. Otherwise rely on normal | 596 // Only restart the timer if the poll succeeded. Otherwise rely on normal |
| 610 // failure handling to retry with backoff. | 597 // failure handling to retry with backoff. |
| 611 if (success) { | 598 if (success) { |
| 612 AdjustPolling(FORCE_RESET); | 599 AdjustPolling(FORCE_RESET); |
| 613 HandleSuccess(); | 600 HandleSuccess(); |
| 614 } else { | 601 } else { |
| 615 HandleFailure(cycle->status_controller().model_neutral_state()); | 602 HandleFailure(cycle->status_controller().model_neutral_state()); |
| 616 } | 603 } |
| 617 } | 604 } |
| 618 | 605 |
| 619 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { | 606 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { |
| 620 DCHECK(CalledOnValidThread()); | 607 DCHECK(CalledOnValidThread()); |
| 621 base::TimeTicks now = TimeTicks::Now(); | 608 TimeTicks now = TimeTicks::Now(); |
| 622 // Update timing information for how often datatypes are triggering nudges. | 609 // Update timing information for how often datatypes are triggering nudges. |
| 623 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { | 610 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { |
| 624 base::TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()]; | 611 TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()]; |
| 625 last_local_nudges_by_model_type_[iter.Get()] = now; | 612 last_local_nudges_by_model_type_[iter.Get()] = now; |
| 626 if (previous.is_null()) | 613 if (previous.is_null()) |
| 627 continue; | 614 continue; |
| 628 | 615 |
| 629 #define PER_DATA_TYPE_MACRO(type_str) \ | 616 #define PER_DATA_TYPE_MACRO(type_str) \ |
| 630 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); | 617 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); |
| 631 SYNC_DATA_TYPE_HISTOGRAM(iter.Get()); | 618 SYNC_DATA_TYPE_HISTOGRAM(iter.Get()); |
| 632 #undef PER_DATA_TYPE_MACRO | 619 #undef PER_DATA_TYPE_MACRO |
| 633 } | 620 } |
| 634 } | 621 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 683 &SyncSchedulerImpl::PollTimerCallback); | 670 &SyncSchedulerImpl::PollTimerCallback); |
| 684 } | 671 } |
| 685 | 672 |
| 686 void SyncSchedulerImpl::RestartWaiting() { | 673 void SyncSchedulerImpl::RestartWaiting() { |
| 687 CHECK(wait_interval_.get()); | 674 CHECK(wait_interval_.get()); |
| 688 DCHECK(wait_interval_->length >= TimeDelta::FromSeconds(0)); | 675 DCHECK(wait_interval_->length >= TimeDelta::FromSeconds(0)); |
| 689 NotifyRetryTime(base::Time::Now() + wait_interval_->length); | 676 NotifyRetryTime(base::Time::Now() + wait_interval_->length); |
| 690 SDVLOG(2) << "Starting WaitInterval timer of length " | 677 SDVLOG(2) << "Starting WaitInterval timer of length " |
| 691 << wait_interval_->length.InMilliseconds() << "ms."; | 678 << wait_interval_->length.InMilliseconds() << "ms."; |
| 692 if (wait_interval_->mode == WaitInterval::THROTTLED) { | 679 if (wait_interval_->mode == WaitInterval::THROTTLED) { |
| 693 pending_wakeup_timer_.Start(FROM_HERE, wait_interval_->length, | 680 global_wakeup_timer_.Start(FROM_HERE, wait_interval_->length, |
| 694 base::Bind(&SyncSchedulerImpl::Unthrottle, | 681 base::Bind(&SyncSchedulerImpl::Unthrottle, |
| 695 weak_ptr_factory_.GetWeakPtr())); | 682 weak_ptr_factory_.GetWeakPtr())); |
| 696 } else { | 683 } else { |
| 697 pending_wakeup_timer_.Start( | 684 global_wakeup_timer_.Start( |
| 698 FROM_HERE, wait_interval_->length, | 685 FROM_HERE, wait_interval_->length, |
| 699 base::Bind(&SyncSchedulerImpl::ExponentialBackoffRetry, | 686 base::Bind(&SyncSchedulerImpl::ExponentialBackoffRetry, |
| 700 weak_ptr_factory_.GetWeakPtr())); | 687 weak_ptr_factory_.GetWeakPtr())); |
| 701 } | 688 } |
| 702 } | 689 } |
| 703 | 690 |
| 704 void SyncSchedulerImpl::Stop() { | 691 void SyncSchedulerImpl::Stop() { |
| 705 DCHECK(CalledOnValidThread()); | 692 DCHECK(CalledOnValidThread()); |
| 706 SDVLOG(2) << "Stop called"; | 693 SDVLOG(2) << "Stop called"; |
| 707 | 694 |
| 708 // Kill any in-flight method calls. | 695 // Kill any in-flight method calls. |
| 709 weak_ptr_factory_.InvalidateWeakPtrs(); | 696 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 710 wait_interval_.reset(); | 697 wait_interval_.reset(); |
| 711 NotifyRetryTime(base::Time()); | 698 NotifyRetryTime(base::Time()); |
| 712 poll_timer_.Stop(); | 699 poll_timer_.Stop(); |
| 713 pending_wakeup_timer_.Stop(); | 700 global_wakeup_timer_.Stop(); |
| 701 type_wakeup_timer_.Stop(); | |
| 714 pending_configure_params_.reset(); | 702 pending_configure_params_.reset(); |
| 715 pending_clear_params_.reset(); | 703 pending_clear_params_.reset(); |
| 716 if (started_) | 704 if (started_) |
| 717 started_ = false; | 705 started_ = false; |
| 718 } | 706 } |
| 719 | 707 |
| 720 // This is the only place where we invoke DoSyncCycleJob with canary | 708 // This is the only place where we invoke DoSyncCycleJob with canary |
| 721 // privileges. Everyone else should use NORMAL_PRIORITY. | 709 // privileges. Everyone else should use NORMAL_PRIORITY. |
| 722 void SyncSchedulerImpl::TryCanaryJob() { | 710 void SyncSchedulerImpl::TryCanaryJob() { |
| 723 next_sync_cycle_job_priority_ = CANARY_PRIORITY; | 711 next_sync_cycle_job_priority_ = CANARY_PRIORITY; |
| 724 SDVLOG(2) << "Attempting canary job"; | 712 SDVLOG(2) << "Attempting canary job"; |
| 725 TrySyncCycleJob(); | 713 TrySyncCycleJob(); |
| 726 } | 714 } |
| 727 | 715 |
| 728 void SyncSchedulerImpl::TrySyncCycleJob() { | 716 void SyncSchedulerImpl::TrySyncCycleJob() { |
| 729 // Post call to TrySyncCycleJobImpl on current thread. Later request for | 717 // Post call to TrySyncCycleJobImpl on current thread. Later request for |
| 730 // access token will be here. | 718 // access token will be here. |
| 731 base::ThreadTaskRunnerHandle::Get()->PostTask( | 719 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 732 FROM_HERE, base::Bind(&SyncSchedulerImpl::TrySyncCycleJobImpl, | 720 FROM_HERE, base::Bind(&SyncSchedulerImpl::TrySyncCycleJobImpl, |
| 733 weak_ptr_factory_.GetWeakPtr())); | 721 weak_ptr_factory_.GetWeakPtr())); |
| 734 } | 722 } |
| 735 | 723 |
| 736 void SyncSchedulerImpl::TrySyncCycleJobImpl() { | 724 void SyncSchedulerImpl::TrySyncCycleJobImpl() { |
| 737 JobPriority priority = next_sync_cycle_job_priority_; | 725 JobPriority priority = next_sync_cycle_job_priority_; |
| 738 next_sync_cycle_job_priority_ = NORMAL_PRIORITY; | 726 next_sync_cycle_job_priority_ = NORMAL_PRIORITY; |
| 739 | 727 |
| 740 nudge_tracker_.SetSyncCycleStartTime(base::TimeTicks::Now()); | 728 nudge_tracker_.SetSyncCycleStartTime(TimeTicks::Now()); |
| 741 | 729 |
| 742 DCHECK(CalledOnValidThread()); | 730 DCHECK(CalledOnValidThread()); |
| 743 if (mode_ == CONFIGURATION_MODE) { | 731 if (mode_ == CONFIGURATION_MODE) { |
| 744 if (pending_configure_params_) { | 732 if (pending_configure_params_) { |
| 745 SDVLOG(2) << "Found pending configure job"; | 733 SDVLOG(2) << "Found pending configure job"; |
| 746 DoConfigurationSyncCycleJob(priority); | 734 DoConfigurationSyncCycleJob(priority); |
| 747 } | 735 } |
| 748 } else if (mode_ == CLEAR_SERVER_DATA_MODE) { | 736 } else if (mode_ == CLEAR_SERVER_DATA_MODE) { |
| 749 if (pending_clear_params_) { | 737 if (pending_clear_params_) { |
| 750 DoClearServerDataSyncCycleJob(priority); | 738 DoClearServerDataSyncCycleJob(priority); |
| 751 } | 739 } |
| 752 } else if (CanRunNudgeJobNow(priority)) { | 740 } else if (CanRunNudgeJobNow(priority)) { |
| 753 if (nudge_tracker_.IsSyncRequired()) { | 741 if (nudge_tracker_.IsSyncRequired()) { |
| 754 SDVLOG(2) << "Found pending nudge job"; | 742 SDVLOG(2) << "Found pending nudge job"; |
| 755 DoNudgeSyncCycleJob(priority); | 743 DoNudgeSyncCycleJob(priority); |
| 756 } else if (((base::TimeTicks::Now() - last_poll_reset_) >= | 744 } else if (((TimeTicks::Now() - last_poll_reset_) >= GetPollInterval())) { |
| 757 GetPollInterval())) { | |
| 758 SDVLOG(2) << "Found pending poll"; | 745 SDVLOG(2) << "Found pending poll"; |
| 759 DoPollSyncCycleJob(); | 746 DoPollSyncCycleJob(); |
| 760 } | 747 } |
| 761 } else { | 748 } else { |
| 762 // We must be in an error state. Transitioning out of each of these | 749 // We must be in an error state. Transitioning out of each of these |
| 763 // error states should trigger a canary job. | 750 // error states should trigger a canary job. |
| 764 DCHECK(IsCurrentlyThrottled() || IsBackingOff() || | 751 DCHECK(IsCurrentlyThrottled() || IsBackingOff() || |
| 765 cycle_context_->connection_manager()->HasInvalidAuthToken()); | 752 cycle_context_->connection_manager()->HasInvalidAuthToken()); |
| 766 } | 753 } |
| 767 | 754 |
| 768 if (IsBackingOff() && !pending_wakeup_timer_.IsRunning()) { | 755 if (IsBackingOff() && !global_wakeup_timer_.IsRunning()) { |
| 769 // If we succeeded, our wait interval would have been cleared. If it hasn't | 756 // If we succeeded, our wait interval would have been cleared. If it hasn't |
| 770 // been cleared, then we should increase our backoff interval and schedule | 757 // been cleared, then we should increase our backoff interval and schedule |
| 771 // another retry. | 758 // another retry. |
| 772 TimeDelta length = delay_provider_->GetDelay(wait_interval_->length); | 759 TimeDelta length = delay_provider_->GetDelay(wait_interval_->length); |
| 773 wait_interval_ = base::MakeUnique<WaitInterval>( | 760 wait_interval_ = base::MakeUnique<WaitInterval>( |
| 774 WaitInterval::EXPONENTIAL_BACKOFF, length); | 761 WaitInterval::EXPONENTIAL_BACKOFF, length); |
| 775 SDVLOG(2) << "Sync cycle failed. Will back off for " | 762 SDVLOG(2) << "Sync cycle failed. Will back off for " |
| 776 << wait_interval_->length.InMilliseconds() << "ms."; | 763 << wait_interval_->length.InMilliseconds() << "ms."; |
| 777 RestartWaiting(); | 764 RestartWaiting(); |
| 778 } | 765 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 799 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); | 786 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); |
| 800 | 787 |
| 801 // We treat this as a 'canary' in the sense that it was originally scheduled | 788 // We treat this as a 'canary' in the sense that it was originally scheduled |
| 802 // to run some time ago, failed, and we now want to retry, versus a job that | 789 // to run some time ago, failed, and we now want to retry, versus a job that |
| 803 // was just created (e.g via ScheduleNudgeImpl). The main implication is | 790 // was just created (e.g via ScheduleNudgeImpl). The main implication is |
| 804 // that we're careful to update routing info (etc) with such potentially | 791 // that we're careful to update routing info (etc) with such potentially |
| 805 // stale canary jobs. | 792 // stale canary jobs. |
| 806 TryCanaryJob(); | 793 TryCanaryJob(); |
| 807 } | 794 } |
| 808 | 795 |
| 809 void SyncSchedulerImpl::TypeUnthrottle(base::TimeTicks unthrottle_time) { | 796 void SyncSchedulerImpl::TypesUnblock(TimeTicks unbackoff_time) { |
|
Nicolas Zea
2016/11/09 00:21:25
I think naming this method something like OnTypesU
Gang Wu
2016/11/10 21:56:51
Done.
| |
| 810 DCHECK(CalledOnValidThread()); | 797 DCHECK(CalledOnValidThread()); |
| 811 nudge_tracker_.UpdateTypeThrottlingState(unthrottle_time); | 798 nudge_tracker_.UpdateTypeThrottlingAndBackoffState(unbackoff_time); |
| 812 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); | 799 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); |
| 800 NotifyBackedOffTypesChanged(nudge_tracker_.GetBackedOffTypes()); | |
| 813 | 801 |
| 802 // If there are some datatype still throttling or backoff, find the closest | |
|
Nicolas Zea
2016/11/09 00:21:25
"still throttling or backoff" -> "still throttled
Gang Wu
2016/11/10 21:56:51
Done.
| |
| 803 // time and schedule SyncSchedulerImpl::TypesUnblock with the closest time. | |
| 804 const TimeTicks now = TimeTicks::Now(); | |
| 805 TimeDelta time_until_next_unblock = TimeDelta::Max(); | |
| 814 if (nudge_tracker_.IsAnyTypeThrottled()) { | 806 if (nudge_tracker_.IsAnyTypeThrottled()) { |
| 815 const base::TimeTicks now = base::TimeTicks::Now(); | 807 time_until_next_unblock = nudge_tracker_.GetTimeUntilNextUnthrottle(now); |
| 816 base::TimeDelta time_until_next_unthrottle = | 808 } |
| 817 nudge_tracker_.GetTimeUntilNextUnthrottle(now); | 809 if (nudge_tracker_.IsAnyTypeBackedOff()) { |
| 818 type_unthrottle_timer_.Start(FROM_HERE, time_until_next_unthrottle, | 810 time_until_next_unblock = std::min( |
| 819 base::Bind(&SyncSchedulerImpl::TypeUnthrottle, | 811 time_until_next_unblock, nudge_tracker_.GetTimeUntilNextUnbackoff(now)); |
| 820 weak_ptr_factory_.GetWeakPtr(), | 812 } |
| 821 now + time_until_next_unthrottle)); | 813 if (!time_until_next_unblock.is_max()) { |
| 814 type_wakeup_timer_.Start(FROM_HERE, time_until_next_unblock, | |
| 815 base::Bind(&SyncSchedulerImpl::TypesUnblock, | |
| 816 weak_ptr_factory_.GetWeakPtr(), | |
| 817 now + time_until_next_unblock)); | |
|
Nicolas Zea
2016/11/09 00:21:25
as mentioned earlier, it's not clear to me why we
Gang Wu
2016/11/10 21:56:51
Done.
| |
| 822 } | 818 } |
| 823 | 819 |
| 824 // Maybe this is a good time to run a nudge job. Let's try it. | 820 // Maybe this is a good time to run a nudge job. Let's try it. |
| 825 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) | 821 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) |
| 826 TrySyncCycleJob(); | 822 TrySyncCycleJob(); |
| 827 } | 823 } |
| 828 | 824 |
| 829 void SyncSchedulerImpl::PerformDelayedNudge() { | 825 void SyncSchedulerImpl::PerformDelayedNudge() { |
| 830 // Circumstances may have changed since we scheduled this delayed nudge. | 826 // Circumstances may have changed since we scheduled this delayed nudge. |
| 831 // We must check to see if it's OK to run the job before we do so. | 827 // We must check to see if it's OK to run the job before we do so. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 846 void SyncSchedulerImpl::NotifyRetryTime(base::Time retry_time) { | 842 void SyncSchedulerImpl::NotifyRetryTime(base::Time retry_time) { |
| 847 for (auto& observer : *cycle_context_->listeners()) | 843 for (auto& observer : *cycle_context_->listeners()) |
| 848 observer.OnRetryTimeChanged(retry_time); | 844 observer.OnRetryTimeChanged(retry_time); |
| 849 } | 845 } |
| 850 | 846 |
| 851 void SyncSchedulerImpl::NotifyThrottledTypesChanged(ModelTypeSet types) { | 847 void SyncSchedulerImpl::NotifyThrottledTypesChanged(ModelTypeSet types) { |
| 852 for (auto& observer : *cycle_context_->listeners()) | 848 for (auto& observer : *cycle_context_->listeners()) |
| 853 observer.OnThrottledTypesChanged(types); | 849 observer.OnThrottledTypesChanged(types); |
| 854 } | 850 } |
| 855 | 851 |
| 852 void SyncSchedulerImpl::NotifyBackedOffTypesChanged(ModelTypeSet types) { | |
| 853 for (auto& observer : *cycle_context_->listeners()) | |
| 854 observer.OnBackedOffTypesChanged(types); | |
| 855 } | |
| 856 | |
| 856 bool SyncSchedulerImpl::IsBackingOff() const { | 857 bool SyncSchedulerImpl::IsBackingOff() const { |
| 857 DCHECK(CalledOnValidThread()); | 858 DCHECK(CalledOnValidThread()); |
| 858 return wait_interval_.get() && | 859 return wait_interval_.get() && |
| 859 wait_interval_->mode == WaitInterval::EXPONENTIAL_BACKOFF; | 860 wait_interval_->mode == WaitInterval::EXPONENTIAL_BACKOFF; |
| 860 } | 861 } |
| 861 | 862 |
| 862 void SyncSchedulerImpl::OnThrottled(const base::TimeDelta& throttle_duration) { | 863 void SyncSchedulerImpl::OnThrottled(const TimeDelta& throttle_duration) { |
| 863 DCHECK(CalledOnValidThread()); | 864 DCHECK(CalledOnValidThread()); |
| 864 wait_interval_ = base::MakeUnique<WaitInterval>(WaitInterval::THROTTLED, | 865 wait_interval_ = base::MakeUnique<WaitInterval>(WaitInterval::THROTTLED, |
| 865 throttle_duration); | 866 throttle_duration); |
| 866 NotifyRetryTime(base::Time::Now() + wait_interval_->length); | 867 NotifyRetryTime(base::Time::Now() + wait_interval_->length); |
| 867 NotifyThrottledTypesChanged(ModelTypeSet::All()); | 868 NotifyThrottledTypesChanged(ModelTypeSet::All()); |
| 868 } | 869 } |
| 869 | 870 |
| 870 void SyncSchedulerImpl::OnTypesThrottled( | 871 void SyncSchedulerImpl::OnTypesThrottled(ModelTypeSet types, |
| 871 ModelTypeSet types, | 872 const TimeDelta& throttle_duration) { |
| 872 const base::TimeDelta& throttle_duration) { | 873 TimeTicks now = TimeTicks::Now(); |
| 873 base::TimeTicks now = base::TimeTicks::Now(); | |
| 874 | 874 |
| 875 SDVLOG(1) << "Throttling " << ModelTypeSetToString(types) << " for " | 875 SDVLOG(1) << "Throttling " << ModelTypeSetToString(types) << " for " |
| 876 << throttle_duration.InMinutes() << " minutes."; | 876 << throttle_duration.InMinutes() << " minutes."; |
| 877 | 877 |
| 878 nudge_tracker_.SetTypesThrottledUntil(types, throttle_duration, now); | 878 nudge_tracker_.SetTypesThrottledUntil(types, throttle_duration, now); |
| 879 base::TimeDelta time_until_next_unthrottle = | 879 TimeDelta time_until_next_unthrottle = |
| 880 nudge_tracker_.GetTimeUntilNextUnthrottle(now); | 880 nudge_tracker_.GetTimeUntilNextUnthrottle(now); |
| 881 type_unthrottle_timer_.Start(FROM_HERE, time_until_next_unthrottle, | 881 type_wakeup_timer_.Start(FROM_HERE, time_until_next_unthrottle, |
|
Nicolas Zea
2016/11/09 00:21:25
Why do we need a separate timer? Can't we reuse th
Gang Wu
2016/11/10 21:56:51
Done.
| |
| 882 base::Bind(&SyncSchedulerImpl::TypeUnthrottle, | 882 base::Bind(&SyncSchedulerImpl::TypesUnblock, |
| 883 weak_ptr_factory_.GetWeakPtr(), | 883 weak_ptr_factory_.GetWeakPtr(), |
| 884 now + time_until_next_unthrottle)); | 884 now + time_until_next_unthrottle)); |
| 885 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); | 885 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); |
| 886 } | 886 } |
| 887 | 887 |
| 888 void SyncSchedulerImpl::OnTypesBackedOff(ModelTypeSet types) { | |
| 889 TimeTicks now = TimeTicks::Now(); | |
| 890 | |
| 891 for (ModelTypeSet::Iterator type = types.First(); type.Good(); type.Inc()) { | |
| 892 TimeDelta last_backoff_time = | |
| 893 TimeDelta::FromSeconds(kInitialBackoffRetrySeconds); | |
| 894 if (nudge_tracker_.IsTypeBackedOff(type.Get())) { | |
| 895 last_backoff_time = nudge_tracker_.GetTypeLastBackoffInterval(type.Get()); | |
| 896 } | |
| 897 | |
| 898 TimeDelta length = delay_provider_->GetDelay(last_backoff_time); | |
| 899 nudge_tracker_.SetTypeBackedOff(type.Get(), length, now); | |
| 900 SDVLOG(1) << "Backing off " << ModelTypeToString(type.Get()) << " for " | |
| 901 << length.InSeconds() << " second."; | |
| 902 } | |
| 903 TimeDelta time_until_next_unbackoff = | |
| 904 nudge_tracker_.GetTimeUntilNextUnbackoff(now); | |
| 905 type_wakeup_timer_.Start(FROM_HERE, time_until_next_unbackoff, | |
| 906 base::Bind(&SyncSchedulerImpl::TypesUnblock, | |
| 907 weak_ptr_factory_.GetWeakPtr(), | |
| 908 now + time_until_next_unbackoff)); | |
| 909 NotifyBackedOffTypesChanged(nudge_tracker_.GetBackedOffTypes()); | |
| 910 } | |
| 911 | |
| 888 bool SyncSchedulerImpl::IsCurrentlyThrottled() { | 912 bool SyncSchedulerImpl::IsCurrentlyThrottled() { |
| 889 DCHECK(CalledOnValidThread()); | 913 DCHECK(CalledOnValidThread()); |
| 890 return wait_interval_.get() && | 914 return wait_interval_.get() && |
| 891 wait_interval_->mode == WaitInterval::THROTTLED; | 915 wait_interval_->mode == WaitInterval::THROTTLED; |
| 892 } | 916 } |
| 893 | 917 |
| 894 void SyncSchedulerImpl::OnReceivedShortPollIntervalUpdate( | 918 void SyncSchedulerImpl::OnReceivedShortPollIntervalUpdate( |
| 895 const base::TimeDelta& new_interval) { | 919 const TimeDelta& new_interval) { |
| 896 DCHECK(CalledOnValidThread()); | 920 DCHECK(CalledOnValidThread()); |
| 897 if (new_interval == syncer_short_poll_interval_seconds_) | 921 if (new_interval == syncer_short_poll_interval_seconds_) |
| 898 return; | 922 return; |
| 899 SDVLOG(1) << "Updating short poll interval to " << new_interval.InMinutes() | 923 SDVLOG(1) << "Updating short poll interval to " << new_interval.InMinutes() |
| 900 << " minutes."; | 924 << " minutes."; |
| 901 syncer_short_poll_interval_seconds_ = new_interval; | 925 syncer_short_poll_interval_seconds_ = new_interval; |
| 902 AdjustPolling(UPDATE_INTERVAL); | 926 AdjustPolling(UPDATE_INTERVAL); |
| 903 } | 927 } |
| 904 | 928 |
| 905 void SyncSchedulerImpl::OnReceivedLongPollIntervalUpdate( | 929 void SyncSchedulerImpl::OnReceivedLongPollIntervalUpdate( |
| 906 const base::TimeDelta& new_interval) { | 930 const TimeDelta& new_interval) { |
| 907 DCHECK(CalledOnValidThread()); | 931 DCHECK(CalledOnValidThread()); |
| 908 if (new_interval == syncer_long_poll_interval_seconds_) | 932 if (new_interval == syncer_long_poll_interval_seconds_) |
| 909 return; | 933 return; |
| 910 SDVLOG(1) << "Updating long poll interval to " << new_interval.InMinutes() | 934 SDVLOG(1) << "Updating long poll interval to " << new_interval.InMinutes() |
| 911 << " minutes."; | 935 << " minutes."; |
| 912 syncer_long_poll_interval_seconds_ = new_interval; | 936 syncer_long_poll_interval_seconds_ = new_interval; |
| 913 AdjustPolling(UPDATE_INTERVAL); | 937 AdjustPolling(UPDATE_INTERVAL); |
| 914 } | 938 } |
| 915 | 939 |
| 916 void SyncSchedulerImpl::OnReceivedCustomNudgeDelays( | 940 void SyncSchedulerImpl::OnReceivedCustomNudgeDelays( |
| 917 const std::map<ModelType, base::TimeDelta>& nudge_delays) { | 941 const std::map<ModelType, TimeDelta>& nudge_delays) { |
| 918 DCHECK(CalledOnValidThread()); | 942 DCHECK(CalledOnValidThread()); |
| 919 nudge_tracker_.OnReceivedCustomNudgeDelays(nudge_delays); | 943 nudge_tracker_.OnReceivedCustomNudgeDelays(nudge_delays); |
| 920 } | 944 } |
| 921 | 945 |
| 922 void SyncSchedulerImpl::OnReceivedClientInvalidationHintBufferSize(int size) { | 946 void SyncSchedulerImpl::OnReceivedClientInvalidationHintBufferSize(int size) { |
| 923 if (size > 0) | 947 if (size > 0) |
| 924 nudge_tracker_.SetHintBufferSize(size); | 948 nudge_tracker_.SetHintBufferSize(size); |
| 925 else | 949 else |
| 926 NOTREACHED() << "Hint buffer size should be > 0."; | 950 NOTREACHED() << "Hint buffer size should be > 0."; |
| 927 } | 951 } |
| 928 | 952 |
| 929 void SyncSchedulerImpl::OnSyncProtocolError( | 953 void SyncSchedulerImpl::OnSyncProtocolError( |
| 930 const SyncProtocolError& sync_protocol_error) { | 954 const SyncProtocolError& sync_protocol_error) { |
| 931 DCHECK(CalledOnValidThread()); | 955 DCHECK(CalledOnValidThread()); |
| 932 if (ShouldRequestEarlyExit(sync_protocol_error)) { | 956 if (ShouldRequestEarlyExit(sync_protocol_error)) { |
| 933 SDVLOG(2) << "Sync Scheduler requesting early exit."; | 957 SDVLOG(2) << "Sync Scheduler requesting early exit."; |
| 934 Stop(); | 958 Stop(); |
| 935 } | 959 } |
| 936 if (IsActionableError(sync_protocol_error)) { | 960 if (IsActionableError(sync_protocol_error)) { |
| 937 SDVLOG(2) << "OnActionableError"; | 961 SDVLOG(2) << "OnActionableError"; |
| 938 for (auto& observer : *cycle_context_->listeners()) | 962 for (auto& observer : *cycle_context_->listeners()) |
| 939 observer.OnActionableError(sync_protocol_error); | 963 observer.OnActionableError(sync_protocol_error); |
| 940 } | 964 } |
| 941 } | 965 } |
| 942 | 966 |
| 943 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const base::TimeDelta& delay) { | 967 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const TimeDelta& delay) { |
| 944 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + delay); | 968 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + delay); |
| 945 retry_timer_.Start(FROM_HERE, delay, this, | 969 retry_timer_.Start(FROM_HERE, delay, this, |
| 946 &SyncSchedulerImpl::RetryTimerCallback); | 970 &SyncSchedulerImpl::RetryTimerCallback); |
| 947 } | 971 } |
| 948 | 972 |
| 949 void SyncSchedulerImpl::OnReceivedMigrationRequest(ModelTypeSet types) { | 973 void SyncSchedulerImpl::OnReceivedMigrationRequest(ModelTypeSet types) { |
| 950 for (auto& observer : *cycle_context_->listeners()) | 974 for (auto& observer : *cycle_context_->listeners()) |
| 951 observer.OnMigrationRequested(types); | 975 observer.OnMigrationRequested(types); |
| 952 } | 976 } |
| 953 | 977 |
| 954 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { | 978 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { |
| 955 DCHECK(CalledOnValidThread()); | 979 DCHECK(CalledOnValidThread()); |
| 956 cycle_context_->set_notifications_enabled(notifications_enabled); | 980 cycle_context_->set_notifications_enabled(notifications_enabled); |
| 957 if (notifications_enabled) | 981 if (notifications_enabled) |
| 958 nudge_tracker_.OnInvalidationsEnabled(); | 982 nudge_tracker_.OnInvalidationsEnabled(); |
| 959 else | 983 else |
| 960 nudge_tracker_.OnInvalidationsDisabled(); | 984 nudge_tracker_.OnInvalidationsDisabled(); |
| 961 } | 985 } |
| 962 | 986 |
| 963 #undef SDVLOG_LOC | 987 #undef SDVLOG_LOC |
| 964 | 988 |
| 965 #undef SDVLOG | 989 #undef SDVLOG |
| 966 | 990 |
| 967 #undef SLOG | 991 #undef SLOG |
| 968 | 992 |
| 969 #undef ENUM_CASE | 993 #undef ENUM_CASE |
| 970 | 994 |
| 971 } // namespace syncer | 995 } // namespace syncer |
| OLD | NEW |