| 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 blocked_types = nudge_tracker_.GetBlockedTypes(); |
| 277 return Difference(enabled_protocol_types, throttled_types); | 259 return Difference(enabled_protocol_types, blocked_types); |
| 278 } | 260 } |
| 279 | 261 |
| 280 void SyncSchedulerImpl::SendInitialSnapshot() { | 262 void SyncSchedulerImpl::SendInitialSnapshot() { |
| 281 DCHECK(CalledOnValidThread()); | 263 DCHECK(CalledOnValidThread()); |
| 282 std::unique_ptr<SyncCycle> dummy(SyncCycle::Build(cycle_context_, this)); | 264 std::unique_ptr<SyncCycle> dummy(SyncCycle::Build(cycle_context_, this)); |
| 283 SyncCycleEvent event(SyncCycleEvent::STATUS_CHANGED); | 265 SyncCycleEvent event(SyncCycleEvent::STATUS_CHANGED); |
| 284 event.snapshot = dummy->TakeSnapshot(); | 266 event.snapshot = dummy->TakeSnapshot(); |
| 285 for (auto& observer : *cycle_context_->listeners()) | 267 for (auto& observer : *cycle_context_->listeners()) |
| 286 observer.OnSyncCycleEvent(event); | 268 observer.OnSyncCycleEvent(event); |
| 287 } | 269 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 | 347 |
| 366 bool SyncSchedulerImpl::CanRunNudgeJobNow(JobPriority priority) { | 348 bool SyncSchedulerImpl::CanRunNudgeJobNow(JobPriority priority) { |
| 367 DCHECK(CalledOnValidThread()); | 349 DCHECK(CalledOnValidThread()); |
| 368 | 350 |
| 369 if (!CanRunJobNow(priority)) { | 351 if (!CanRunJobNow(priority)) { |
| 370 SDVLOG(1) << "Unable to run a nudge job right now"; | 352 SDVLOG(1) << "Unable to run a nudge job right now"; |
| 371 return false; | 353 return false; |
| 372 } | 354 } |
| 373 | 355 |
| 374 const ModelTypeSet enabled_types = cycle_context_->GetEnabledTypes(); | 356 const ModelTypeSet enabled_types = cycle_context_->GetEnabledTypes(); |
| 375 if (nudge_tracker_.GetThrottledTypes().HasAll(enabled_types)) { | 357 if (nudge_tracker_.GetBlockedTypes().HasAll(enabled_types)) { |
| 376 SDVLOG(1) << "Not running a nudge because we're fully type throttled."; | 358 SDVLOG(1) << "Not running a nudge because we're fully type throttled or " |
| 359 "backed off."; |
| 377 return false; | 360 return false; |
| 378 } | 361 } |
| 379 | 362 |
| 380 if (mode_ != NORMAL_MODE) { | 363 if (mode_ != NORMAL_MODE) { |
| 381 SDVLOG(1) << "Not running nudge because we're not in normal mode."; | 364 SDVLOG(1) << "Not running nudge because we're not in normal mode."; |
| 382 return false; | 365 return false; |
| 383 } | 366 } |
| 384 | 367 |
| 385 return true; | 368 return true; |
| 386 } | 369 } |
| 387 | 370 |
| 388 void SyncSchedulerImpl::ScheduleLocalNudge( | 371 void SyncSchedulerImpl::ScheduleLocalNudge( |
| 389 ModelTypeSet types, | 372 ModelTypeSet types, |
| 390 const tracked_objects::Location& nudge_location) { | 373 const tracked_objects::Location& nudge_location) { |
| 391 DCHECK(CalledOnValidThread()); | 374 DCHECK(CalledOnValidThread()); |
| 392 DCHECK(!types.Empty()); | 375 DCHECK(!types.Empty()); |
| 393 | 376 |
| 394 SDVLOG_LOC(nudge_location, 2) << "Scheduling sync because of local change to " | 377 SDVLOG_LOC(nudge_location, 2) << "Scheduling sync because of local change to " |
| 395 << ModelTypeSetToString(types); | 378 << ModelTypeSetToString(types); |
| 396 UpdateNudgeTimeRecords(types); | 379 UpdateNudgeTimeRecords(types); |
| 397 base::TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(types); | 380 TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(types); |
| 398 ScheduleNudgeImpl(nudge_delay, nudge_location); | 381 ScheduleNudgeImpl(nudge_delay, nudge_location); |
| 399 } | 382 } |
| 400 | 383 |
| 401 void SyncSchedulerImpl::ScheduleLocalRefreshRequest( | 384 void SyncSchedulerImpl::ScheduleLocalRefreshRequest( |
| 402 ModelTypeSet types, | 385 ModelTypeSet types, |
| 403 const tracked_objects::Location& nudge_location) { | 386 const tracked_objects::Location& nudge_location) { |
| 404 DCHECK(CalledOnValidThread()); | 387 DCHECK(CalledOnValidThread()); |
| 405 DCHECK(!types.Empty()); | 388 DCHECK(!types.Empty()); |
| 406 | 389 |
| 407 SDVLOG_LOC(nudge_location, 2) | 390 SDVLOG_LOC(nudge_location, 2) |
| 408 << "Scheduling sync because of local refresh request for " | 391 << "Scheduling sync because of local refresh request for " |
| 409 << ModelTypeSetToString(types); | 392 << ModelTypeSetToString(types); |
| 410 base::TimeDelta nudge_delay = nudge_tracker_.RecordLocalRefreshRequest(types); | 393 TimeDelta nudge_delay = nudge_tracker_.RecordLocalRefreshRequest(types); |
| 411 ScheduleNudgeImpl(nudge_delay, nudge_location); | 394 ScheduleNudgeImpl(nudge_delay, nudge_location); |
| 412 } | 395 } |
| 413 | 396 |
| 414 void SyncSchedulerImpl::ScheduleInvalidationNudge( | 397 void SyncSchedulerImpl::ScheduleInvalidationNudge( |
| 415 ModelType model_type, | 398 ModelType model_type, |
| 416 std::unique_ptr<InvalidationInterface> invalidation, | 399 std::unique_ptr<InvalidationInterface> invalidation, |
| 417 const tracked_objects::Location& nudge_location) { | 400 const tracked_objects::Location& nudge_location) { |
| 418 DCHECK(CalledOnValidThread()); | 401 DCHECK(CalledOnValidThread()); |
| 419 | 402 |
| 420 SDVLOG_LOC(nudge_location, 2) | 403 SDVLOG_LOC(nudge_location, 2) |
| 421 << "Scheduling sync because we received invalidation for " | 404 << "Scheduling sync because we received invalidation for " |
| 422 << ModelTypeToString(model_type); | 405 << ModelTypeToString(model_type); |
| 423 base::TimeDelta nudge_delay = nudge_tracker_.RecordRemoteInvalidation( | 406 TimeDelta nudge_delay = nudge_tracker_.RecordRemoteInvalidation( |
| 424 model_type, std::move(invalidation)); | 407 model_type, std::move(invalidation)); |
| 425 ScheduleNudgeImpl(nudge_delay, nudge_location); | 408 ScheduleNudgeImpl(nudge_delay, nudge_location); |
| 426 } | 409 } |
| 427 | 410 |
| 428 void SyncSchedulerImpl::ScheduleInitialSyncNudge(ModelType model_type) { | 411 void SyncSchedulerImpl::ScheduleInitialSyncNudge(ModelType model_type) { |
| 429 DCHECK(CalledOnValidThread()); | 412 DCHECK(CalledOnValidThread()); |
| 430 | 413 |
| 431 SDVLOG(2) << "Scheduling non-blocking initial sync for " | 414 SDVLOG(2) << "Scheduling non-blocking initial sync for " |
| 432 << ModelTypeToString(model_type); | 415 << ModelTypeToString(model_type); |
| 433 nudge_tracker_.RecordInitialSyncRequired(model_type); | 416 nudge_tracker_.RecordInitialSyncRequired(model_type); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 448 return; | 431 return; |
| 449 } | 432 } |
| 450 | 433 |
| 451 SDVLOG_LOC(nudge_location, 2) << "In ScheduleNudgeImpl with delay " | 434 SDVLOG_LOC(nudge_location, 2) << "In ScheduleNudgeImpl with delay " |
| 452 << delay.InMilliseconds() << " ms"; | 435 << delay.InMilliseconds() << " ms"; |
| 453 | 436 |
| 454 if (!CanRunNudgeJobNow(NORMAL_PRIORITY)) | 437 if (!CanRunNudgeJobNow(NORMAL_PRIORITY)) |
| 455 return; | 438 return; |
| 456 | 439 |
| 457 TimeTicks incoming_run_time = TimeTicks::Now() + delay; | 440 TimeTicks incoming_run_time = TimeTicks::Now() + delay; |
| 458 if (!scheduled_nudge_time_.is_null() && | 441 if (pending_wakeup_timer_.IsRunning() && |
| 459 (scheduled_nudge_time_ < incoming_run_time)) { | 442 (pending_wakeup_timer_.desired_run_time() < incoming_run_time)) { |
| 460 // Old job arrives sooner than this one. Don't reschedule it. | 443 // Old job arrives sooner than this one. Don't reschedule it. |
| 461 return; | 444 return; |
| 462 } | 445 } |
| 463 | 446 |
| 464 // Either there is no existing nudge in flight or the incoming nudge should be | 447 // 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 | 448 // made to arrive first (preempt) the existing nudge. We reschedule in either |
| 466 // case. | 449 // case. |
| 467 SDVLOG_LOC(nudge_location, 2) << "Scheduling a nudge with " | 450 SDVLOG_LOC(nudge_location, 2) << "Scheduling a nudge with " |
| 468 << delay.InMilliseconds() << " ms delay"; | 451 << delay.InMilliseconds() << " ms delay"; |
| 469 scheduled_nudge_time_ = incoming_run_time; | |
| 470 pending_wakeup_timer_.Start( | 452 pending_wakeup_timer_.Start( |
| 471 nudge_location, delay, base::Bind(&SyncSchedulerImpl::PerformDelayedNudge, | 453 nudge_location, delay, base::Bind(&SyncSchedulerImpl::PerformDelayedNudge, |
| 472 weak_ptr_factory_.GetWeakPtr())); | 454 weak_ptr_factory_.GetWeakPtr())); |
| 473 } | 455 } |
| 474 | 456 |
| 475 const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) { | 457 const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) { |
| 476 switch (mode) { | 458 switch (mode) { |
| 477 ENUM_CASE(CONFIGURATION_MODE); | 459 ENUM_CASE(CONFIGURATION_MODE); |
| 478 ENUM_CASE(CLEAR_SERVER_DATA_MODE); | 460 ENUM_CASE(CLEAR_SERVER_DATA_MODE); |
| 479 ENUM_CASE(NORMAL_MODE); | 461 ENUM_CASE(NORMAL_MODE); |
| 480 } | 462 } |
| 481 return ""; | 463 return ""; |
| 482 } | 464 } |
| 483 | 465 |
| 484 void SyncSchedulerImpl::SetDefaultNudgeDelay(base::TimeDelta delay_ms) { | 466 void SyncSchedulerImpl::SetDefaultNudgeDelay(TimeDelta delay_ms) { |
| 485 DCHECK(CalledOnValidThread()); | 467 DCHECK(CalledOnValidThread()); |
| 486 nudge_tracker_.SetDefaultNudgeDelay(delay_ms); | 468 nudge_tracker_.SetDefaultNudgeDelay(delay_ms); |
| 487 } | 469 } |
| 488 | 470 |
| 489 void SyncSchedulerImpl::DoNudgeSyncCycleJob(JobPriority priority) { | 471 void SyncSchedulerImpl::DoNudgeSyncCycleJob(JobPriority priority) { |
| 490 DCHECK(CalledOnValidThread()); | 472 DCHECK(CalledOnValidThread()); |
| 491 DCHECK(CanRunNudgeJobNow(priority)); | 473 DCHECK(CanRunNudgeJobNow(priority)); |
| 492 | 474 |
| 493 DVLOG(2) << "Will run normal mode sync cycle with types " | 475 DVLOG(2) << "Will run normal mode sync cycle with types " |
| 494 << ModelTypeSetToString(cycle_context_->GetEnabledTypes()); | 476 << ModelTypeSetToString(cycle_context_->GetEnabledTypes()); |
| 495 std::unique_ptr<SyncCycle> cycle(SyncCycle::Build(cycle_context_, this)); | 477 std::unique_ptr<SyncCycle> cycle(SyncCycle::Build(cycle_context_, this)); |
| 496 bool success = syncer_->NormalSyncShare(GetEnabledAndUnthrottledTypes(), | 478 bool success = syncer_->NormalSyncShare(GetEnabledAndUnblockedTypes(), |
| 497 &nudge_tracker_, cycle.get()); | 479 &nudge_tracker_, cycle.get()); |
| 498 | 480 |
| 499 if (success) { | 481 if (success) { |
| 500 // That cycle took care of any outstanding work we had. | 482 // That cycle took care of any outstanding work we had. |
| 501 SDVLOG(2) << "Nudge succeeded."; | 483 SDVLOG(2) << "Nudge succeeded."; |
| 502 nudge_tracker_.RecordSuccessfulSyncCycle(); | 484 nudge_tracker_.RecordSuccessfulSyncCycle(); |
| 503 scheduled_nudge_time_ = base::TimeTicks(); | |
| 504 HandleSuccess(); | 485 HandleSuccess(); |
| 505 | 486 |
| 506 // If this was a canary, we may need to restart the poll timer (the poll | 487 // 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 | 488 // timer may have fired while the scheduler was in an error state, ignoring |
| 508 // the poll). | 489 // the poll). |
| 509 if (!poll_timer_.IsRunning()) { | 490 if (!poll_timer_.IsRunning()) { |
| 510 SDVLOG(1) << "Canary succeeded, restarting polling."; | 491 SDVLOG(1) << "Canary succeeded, restarting polling."; |
| 511 AdjustPolling(UPDATE_INTERVAL); | 492 AdjustPolling(UPDATE_INTERVAL); |
| 512 } | 493 } |
| 513 } else { | 494 } else { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 wait_interval_ = base::MakeUnique<WaitInterval>( | 575 wait_interval_ = base::MakeUnique<WaitInterval>( |
| 595 WaitInterval::EXPONENTIAL_BACKOFF, length); | 576 WaitInterval::EXPONENTIAL_BACKOFF, length); |
| 596 SDVLOG(2) << "Sync cycle failed. Will back off for " | 577 SDVLOG(2) << "Sync cycle failed. Will back off for " |
| 597 << wait_interval_->length.InMilliseconds() << "ms."; | 578 << wait_interval_->length.InMilliseconds() << "ms."; |
| 598 } | 579 } |
| 599 RestartWaiting(); | 580 RestartWaiting(); |
| 600 } | 581 } |
| 601 | 582 |
| 602 void SyncSchedulerImpl::DoPollSyncCycleJob() { | 583 void SyncSchedulerImpl::DoPollSyncCycleJob() { |
| 603 SDVLOG(2) << "Polling with types " | 584 SDVLOG(2) << "Polling with types " |
| 604 << ModelTypeSetToString(GetEnabledAndUnthrottledTypes()); | 585 << ModelTypeSetToString(GetEnabledAndUnblockedTypes()); |
| 605 std::unique_ptr<SyncCycle> cycle(SyncCycle::Build(cycle_context_, this)); | 586 std::unique_ptr<SyncCycle> cycle(SyncCycle::Build(cycle_context_, this)); |
| 606 bool success = | 587 bool success = |
| 607 syncer_->PollSyncShare(GetEnabledAndUnthrottledTypes(), cycle.get()); | 588 syncer_->PollSyncShare(GetEnabledAndUnblockedTypes(), cycle.get()); |
| 608 | 589 |
| 609 // Only restart the timer if the poll succeeded. Otherwise rely on normal | 590 // Only restart the timer if the poll succeeded. Otherwise rely on normal |
| 610 // failure handling to retry with backoff. | 591 // failure handling to retry with backoff. |
| 611 if (success) { | 592 if (success) { |
| 612 AdjustPolling(FORCE_RESET); | 593 AdjustPolling(FORCE_RESET); |
| 613 HandleSuccess(); | 594 HandleSuccess(); |
| 614 } else { | 595 } else { |
| 615 HandleFailure(cycle->status_controller().model_neutral_state()); | 596 HandleFailure(cycle->status_controller().model_neutral_state()); |
| 616 } | 597 } |
| 617 } | 598 } |
| 618 | 599 |
| 619 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { | 600 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { |
| 620 DCHECK(CalledOnValidThread()); | 601 DCHECK(CalledOnValidThread()); |
| 621 base::TimeTicks now = TimeTicks::Now(); | 602 TimeTicks now = TimeTicks::Now(); |
| 622 // Update timing information for how often datatypes are triggering nudges. | 603 // Update timing information for how often datatypes are triggering nudges. |
| 623 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { | 604 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { |
| 624 base::TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()]; | 605 TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()]; |
| 625 last_local_nudges_by_model_type_[iter.Get()] = now; | 606 last_local_nudges_by_model_type_[iter.Get()] = now; |
| 626 if (previous.is_null()) | 607 if (previous.is_null()) |
| 627 continue; | 608 continue; |
| 628 | 609 |
| 629 #define PER_DATA_TYPE_MACRO(type_str) \ | 610 #define PER_DATA_TYPE_MACRO(type_str) \ |
| 630 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); | 611 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); |
| 631 SYNC_DATA_TYPE_HISTOGRAM(iter.Get()); | 612 SYNC_DATA_TYPE_HISTOGRAM(iter.Get()); |
| 632 #undef PER_DATA_TYPE_MACRO | 613 #undef PER_DATA_TYPE_MACRO |
| 633 } | 614 } |
| 634 } | 615 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 | 658 |
| 678 SDVLOG(1) << "Updating polling delay to " << poll_delay.InMinutes() | 659 SDVLOG(1) << "Updating polling delay to " << poll_delay.InMinutes() |
| 679 << " minutes."; | 660 << " minutes."; |
| 680 | 661 |
| 681 // Adjust poll rate. Start will reset the timer if it was already running. | 662 // Adjust poll rate. Start will reset the timer if it was already running. |
| 682 poll_timer_.Start(FROM_HERE, poll_delay, this, | 663 poll_timer_.Start(FROM_HERE, poll_delay, this, |
| 683 &SyncSchedulerImpl::PollTimerCallback); | 664 &SyncSchedulerImpl::PollTimerCallback); |
| 684 } | 665 } |
| 685 | 666 |
| 686 void SyncSchedulerImpl::RestartWaiting() { | 667 void SyncSchedulerImpl::RestartWaiting() { |
| 687 CHECK(wait_interval_.get()); | 668 if (wait_interval_.get()) { |
| 688 DCHECK(wait_interval_->length >= TimeDelta::FromSeconds(0)); | 669 // Global throttling or backoff |
| 689 NotifyRetryTime(base::Time::Now() + wait_interval_->length); | 670 NotifyRetryTime(base::Time::Now() + wait_interval_->length); |
| 690 SDVLOG(2) << "Starting WaitInterval timer of length " | 671 SDVLOG(2) << "Starting WaitInterval timer of length " |
| 691 << wait_interval_->length.InMilliseconds() << "ms."; | 672 << wait_interval_->length.InMilliseconds() << "ms."; |
| 692 if (wait_interval_->mode == WaitInterval::THROTTLED) { | 673 if (wait_interval_->mode == WaitInterval::THROTTLED) { |
| 693 pending_wakeup_timer_.Start(FROM_HERE, wait_interval_->length, | 674 pending_wakeup_timer_.Start(FROM_HERE, wait_interval_->length, |
| 694 base::Bind(&SyncSchedulerImpl::Unthrottle, | 675 base::Bind(&SyncSchedulerImpl::Unthrottle, |
| 676 weak_ptr_factory_.GetWeakPtr())); |
| 677 } else { |
| 678 pending_wakeup_timer_.Start( |
| 679 FROM_HERE, wait_interval_->length, |
| 680 base::Bind(&SyncSchedulerImpl::ExponentialBackoffRetry, |
| 681 weak_ptr_factory_.GetWeakPtr())); |
| 682 } |
| 683 } else if (nudge_tracker_.IsAnyTypeBlocked()) { |
| 684 // Per-datatype throttled or backed off. |
| 685 TimeDelta time_until_next_unblock = |
| 686 nudge_tracker_.GetTimeUntilNextUnblock(); |
| 687 pending_wakeup_timer_.Start(FROM_HERE, time_until_next_unblock, |
| 688 base::Bind(&SyncSchedulerImpl::OnTypesUnblocked, |
| 695 weak_ptr_factory_.GetWeakPtr())); | 689 weak_ptr_factory_.GetWeakPtr())); |
| 696 } else { | |
| 697 pending_wakeup_timer_.Start( | |
| 698 FROM_HERE, wait_interval_->length, | |
| 699 base::Bind(&SyncSchedulerImpl::ExponentialBackoffRetry, | |
| 700 weak_ptr_factory_.GetWeakPtr())); | |
| 701 } | 690 } |
| 702 } | 691 } |
| 703 | 692 |
| 704 void SyncSchedulerImpl::Stop() { | 693 void SyncSchedulerImpl::Stop() { |
| 705 DCHECK(CalledOnValidThread()); | 694 DCHECK(CalledOnValidThread()); |
| 706 SDVLOG(2) << "Stop called"; | 695 SDVLOG(2) << "Stop called"; |
| 707 | 696 |
| 708 // Kill any in-flight method calls. | 697 // Kill any in-flight method calls. |
| 709 weak_ptr_factory_.InvalidateWeakPtrs(); | 698 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 710 wait_interval_.reset(); | 699 wait_interval_.reset(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 730 // access token will be here. | 719 // access token will be here. |
| 731 base::ThreadTaskRunnerHandle::Get()->PostTask( | 720 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 732 FROM_HERE, base::Bind(&SyncSchedulerImpl::TrySyncCycleJobImpl, | 721 FROM_HERE, base::Bind(&SyncSchedulerImpl::TrySyncCycleJobImpl, |
| 733 weak_ptr_factory_.GetWeakPtr())); | 722 weak_ptr_factory_.GetWeakPtr())); |
| 734 } | 723 } |
| 735 | 724 |
| 736 void SyncSchedulerImpl::TrySyncCycleJobImpl() { | 725 void SyncSchedulerImpl::TrySyncCycleJobImpl() { |
| 737 JobPriority priority = next_sync_cycle_job_priority_; | 726 JobPriority priority = next_sync_cycle_job_priority_; |
| 738 next_sync_cycle_job_priority_ = NORMAL_PRIORITY; | 727 next_sync_cycle_job_priority_ = NORMAL_PRIORITY; |
| 739 | 728 |
| 740 nudge_tracker_.SetSyncCycleStartTime(base::TimeTicks::Now()); | 729 nudge_tracker_.SetSyncCycleStartTime(TimeTicks::Now()); |
| 741 | 730 |
| 742 DCHECK(CalledOnValidThread()); | 731 DCHECK(CalledOnValidThread()); |
| 743 if (mode_ == CONFIGURATION_MODE) { | 732 if (mode_ == CONFIGURATION_MODE) { |
| 744 if (pending_configure_params_) { | 733 if (pending_configure_params_) { |
| 745 SDVLOG(2) << "Found pending configure job"; | 734 SDVLOG(2) << "Found pending configure job"; |
| 746 DoConfigurationSyncCycleJob(priority); | 735 DoConfigurationSyncCycleJob(priority); |
| 747 } | 736 } |
| 748 } else if (mode_ == CLEAR_SERVER_DATA_MODE) { | 737 } else if (mode_ == CLEAR_SERVER_DATA_MODE) { |
| 749 if (pending_clear_params_) { | 738 if (pending_clear_params_) { |
| 750 DoClearServerDataSyncCycleJob(priority); | 739 DoClearServerDataSyncCycleJob(priority); |
| 751 } | 740 } |
| 752 } else if (CanRunNudgeJobNow(priority)) { | 741 } else if (CanRunNudgeJobNow(priority)) { |
| 753 if (nudge_tracker_.IsSyncRequired()) { | 742 if (nudge_tracker_.IsSyncRequired()) { |
| 754 SDVLOG(2) << "Found pending nudge job"; | 743 SDVLOG(2) << "Found pending nudge job"; |
| 755 DoNudgeSyncCycleJob(priority); | 744 DoNudgeSyncCycleJob(priority); |
| 756 } else if (((base::TimeTicks::Now() - last_poll_reset_) >= | 745 } else if (((TimeTicks::Now() - last_poll_reset_) >= GetPollInterval())) { |
| 757 GetPollInterval())) { | |
| 758 SDVLOG(2) << "Found pending poll"; | 746 SDVLOG(2) << "Found pending poll"; |
| 759 DoPollSyncCycleJob(); | 747 DoPollSyncCycleJob(); |
| 760 } | 748 } |
| 761 } else { | 749 } else { |
| 762 // We must be in an error state. Transitioning out of each of these | 750 // We must be in an error state. Transitioning out of each of these |
| 763 // error states should trigger a canary job. | 751 // error states should trigger a canary job. |
| 764 DCHECK(IsCurrentlyThrottled() || IsBackingOff() || | 752 DCHECK(IsCurrentlyThrottled() || IsBackingOff() || |
| 765 cycle_context_->connection_manager()->HasInvalidAuthToken()); | 753 cycle_context_->connection_manager()->HasInvalidAuthToken()); |
| 766 } | 754 } |
| 767 | 755 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 789 TrySyncCycleJob(); | 777 TrySyncCycleJob(); |
| 790 } | 778 } |
| 791 | 779 |
| 792 void SyncSchedulerImpl::Unthrottle() { | 780 void SyncSchedulerImpl::Unthrottle() { |
| 793 DCHECK(CalledOnValidThread()); | 781 DCHECK(CalledOnValidThread()); |
| 794 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode); | 782 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode); |
| 795 | 783 |
| 796 // We're no longer throttled, so clear the wait interval. | 784 // We're no longer throttled, so clear the wait interval. |
| 797 wait_interval_.reset(); | 785 wait_interval_.reset(); |
| 798 NotifyRetryTime(base::Time()); | 786 NotifyRetryTime(base::Time()); |
| 799 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); | 787 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); |
| 800 | 788 |
| 801 // We treat this as a 'canary' in the sense that it was originally scheduled | 789 // 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 | 790 // 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 | 791 // was just created (e.g via ScheduleNudgeImpl). The main implication is |
| 804 // that we're careful to update routing info (etc) with such potentially | 792 // that we're careful to update routing info (etc) with such potentially |
| 805 // stale canary jobs. | 793 // stale canary jobs. |
| 806 TryCanaryJob(); | 794 TryCanaryJob(); |
| 807 } | 795 } |
| 808 | 796 |
| 809 void SyncSchedulerImpl::TypeUnthrottle(base::TimeTicks unthrottle_time) { | 797 void SyncSchedulerImpl::OnTypesUnblocked() { |
| 810 DCHECK(CalledOnValidThread()); | 798 DCHECK(CalledOnValidThread()); |
| 811 nudge_tracker_.UpdateTypeThrottlingState(unthrottle_time); | 799 nudge_tracker_.UpdateTypeThrottlingAndBackoffState(); |
| 812 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); | 800 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); |
| 813 | 801 |
| 814 if (nudge_tracker_.IsAnyTypeThrottled()) { | 802 RestartWaiting(); |
| 815 const base::TimeTicks now = base::TimeTicks::Now(); | |
| 816 base::TimeDelta time_until_next_unthrottle = | |
| 817 nudge_tracker_.GetTimeUntilNextUnthrottle(now); | |
| 818 type_unthrottle_timer_.Start(FROM_HERE, time_until_next_unthrottle, | |
| 819 base::Bind(&SyncSchedulerImpl::TypeUnthrottle, | |
| 820 weak_ptr_factory_.GetWeakPtr(), | |
| 821 now + time_until_next_unthrottle)); | |
| 822 } | |
| 823 | 803 |
| 824 // Maybe this is a good time to run a nudge job. Let's try it. | 804 // Maybe this is a good time to run a nudge job. Let's try it. |
| 825 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) | 805 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) |
| 826 TrySyncCycleJob(); | 806 TrySyncCycleJob(); |
| 827 } | 807 } |
| 828 | 808 |
| 829 void SyncSchedulerImpl::PerformDelayedNudge() { | 809 void SyncSchedulerImpl::PerformDelayedNudge() { |
| 830 // Circumstances may have changed since we scheduled this delayed nudge. | 810 // 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. | 811 // We must check to see if it's OK to run the job before we do so. |
| 832 if (CanRunNudgeJobNow(NORMAL_PRIORITY)) | 812 if (CanRunNudgeJobNow(NORMAL_PRIORITY)) |
| 833 TrySyncCycleJob(); | 813 TrySyncCycleJob(); |
| 834 | 814 |
| 835 // We're not responsible for setting up any retries here. The functions that | 815 // We're not responsible for setting up any retries here. The functions that |
| 836 // first put us into a state that prevents successful sync cycles (eg. global | 816 // first put us into a state that prevents successful sync cycles (eg. global |
| 837 // throttling, type throttling, network errors, transient errors) will also | 817 // throttling, type throttling, network errors, transient errors) will also |
| 838 // setup the appropriate retry logic (eg. retry after timeout, exponential | 818 // setup the appropriate retry logic (eg. retry after timeout, exponential |
| 839 // backoff, retry when the network changes). | 819 // backoff, retry when the network changes). |
| 840 } | 820 } |
| 841 | 821 |
| 842 void SyncSchedulerImpl::ExponentialBackoffRetry() { | 822 void SyncSchedulerImpl::ExponentialBackoffRetry() { |
| 843 TryCanaryJob(); | 823 TryCanaryJob(); |
| 844 } | 824 } |
| 845 | 825 |
| 846 void SyncSchedulerImpl::NotifyRetryTime(base::Time retry_time) { | 826 void SyncSchedulerImpl::NotifyRetryTime(base::Time retry_time) { |
| 847 for (auto& observer : *cycle_context_->listeners()) | 827 for (auto& observer : *cycle_context_->listeners()) |
| 848 observer.OnRetryTimeChanged(retry_time); | 828 observer.OnRetryTimeChanged(retry_time); |
| 849 } | 829 } |
| 850 | 830 |
| 851 void SyncSchedulerImpl::NotifyThrottledTypesChanged(ModelTypeSet types) { | 831 void SyncSchedulerImpl::NotifyBlockedTypesChanged(ModelTypeSet types) { |
| 852 for (auto& observer : *cycle_context_->listeners()) | 832 ModelTypeSet throttled_types; |
| 853 observer.OnThrottledTypesChanged(types); | 833 ModelTypeSet backed_off_types; |
| 834 for (ModelTypeSet::Iterator type_it = types.First(); type_it.Good(); |
| 835 type_it.Inc()) { |
| 836 if (nudge_tracker_.GetTypeBlockingMode(type_it.Get()) == |
| 837 WaitInterval::THROTTLED) { |
| 838 throttled_types.Put(type_it.Get()); |
| 839 } else if (nudge_tracker_.GetTypeBlockingMode(type_it.Get()) == |
| 840 WaitInterval::EXPONENTIAL_BACKOFF) { |
| 841 backed_off_types.Put(type_it.Get()); |
| 842 } |
| 843 } |
| 844 |
| 845 for (auto& observer : *cycle_context_->listeners()) { |
| 846 observer.OnThrottledTypesChanged(throttled_types); |
| 847 observer.OnBackedOffTypesChanged(backed_off_types); |
| 848 } |
| 854 } | 849 } |
| 855 | 850 |
| 856 bool SyncSchedulerImpl::IsBackingOff() const { | 851 bool SyncSchedulerImpl::IsBackingOff() const { |
| 857 DCHECK(CalledOnValidThread()); | 852 DCHECK(CalledOnValidThread()); |
| 858 return wait_interval_.get() && | 853 return wait_interval_.get() && |
| 859 wait_interval_->mode == WaitInterval::EXPONENTIAL_BACKOFF; | 854 wait_interval_->mode == WaitInterval::EXPONENTIAL_BACKOFF; |
| 860 } | 855 } |
| 861 | 856 |
| 862 void SyncSchedulerImpl::OnThrottled(const base::TimeDelta& throttle_duration) { | 857 void SyncSchedulerImpl::OnThrottled(const TimeDelta& throttle_duration) { |
| 863 DCHECK(CalledOnValidThread()); | 858 DCHECK(CalledOnValidThread()); |
| 864 wait_interval_ = base::MakeUnique<WaitInterval>(WaitInterval::THROTTLED, | 859 wait_interval_ = base::MakeUnique<WaitInterval>(WaitInterval::THROTTLED, |
| 865 throttle_duration); | 860 throttle_duration); |
| 866 NotifyRetryTime(base::Time::Now() + wait_interval_->length); | 861 NotifyRetryTime(base::Time::Now() + wait_interval_->length); |
| 867 NotifyThrottledTypesChanged(ModelTypeSet::All()); | 862 |
| 863 for (auto& observer : *cycle_context_->listeners()) { |
| 864 observer.OnThrottledTypesChanged(ModelTypeSet::All()); |
| 865 } |
| 868 } | 866 } |
| 869 | 867 |
| 870 void SyncSchedulerImpl::OnTypesThrottled( | 868 void SyncSchedulerImpl::OnTypesThrottled(ModelTypeSet types, |
| 871 ModelTypeSet types, | 869 const TimeDelta& throttle_duration) { |
| 872 const base::TimeDelta& throttle_duration) { | 870 TimeTicks now = TimeTicks::Now(); |
| 873 base::TimeTicks now = base::TimeTicks::Now(); | |
| 874 | 871 |
| 875 SDVLOG(1) << "Throttling " << ModelTypeSetToString(types) << " for " | 872 SDVLOG(1) << "Throttling " << ModelTypeSetToString(types) << " for " |
| 876 << throttle_duration.InMinutes() << " minutes."; | 873 << throttle_duration.InMinutes() << " minutes."; |
| 877 | 874 |
| 878 nudge_tracker_.SetTypesThrottledUntil(types, throttle_duration, now); | 875 nudge_tracker_.SetTypesThrottledUntil(types, throttle_duration, now); |
| 879 base::TimeDelta time_until_next_unthrottle = | 876 RestartWaiting(); |
| 880 nudge_tracker_.GetTimeUntilNextUnthrottle(now); | 877 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); |
| 881 type_unthrottle_timer_.Start(FROM_HERE, time_until_next_unthrottle, | 878 } |
| 882 base::Bind(&SyncSchedulerImpl::TypeUnthrottle, | 879 |
| 883 weak_ptr_factory_.GetWeakPtr(), | 880 void SyncSchedulerImpl::OnTypesBackedOff(ModelTypeSet types) { |
| 884 now + time_until_next_unthrottle)); | 881 TimeTicks now = TimeTicks::Now(); |
| 885 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); | 882 |
| 883 for (ModelTypeSet::Iterator type = types.First(); type.Good(); type.Inc()) { |
| 884 TimeDelta last_backoff_time = |
| 885 TimeDelta::FromSeconds(kInitialBackoffRetrySeconds); |
| 886 if (nudge_tracker_.GetTypeBlockingMode(type.Get()) == |
| 887 WaitInterval::EXPONENTIAL_BACKOFF_RETRYING) { |
| 888 last_backoff_time = nudge_tracker_.GetTypeLastBackoffInterval(type.Get()); |
| 889 } |
| 890 |
| 891 TimeDelta length = delay_provider_->GetDelay(last_backoff_time); |
| 892 nudge_tracker_.SetTypeBackedOff(type.Get(), length, now); |
| 893 SDVLOG(1) << "Backing off " << ModelTypeToString(type.Get()) << " for " |
| 894 << length.InSeconds() << " second."; |
| 895 } |
| 896 RestartWaiting(); |
| 897 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); |
| 886 } | 898 } |
| 887 | 899 |
| 888 bool SyncSchedulerImpl::IsCurrentlyThrottled() { | 900 bool SyncSchedulerImpl::IsCurrentlyThrottled() { |
| 889 DCHECK(CalledOnValidThread()); | 901 DCHECK(CalledOnValidThread()); |
| 890 return wait_interval_.get() && | 902 return wait_interval_.get() && |
| 891 wait_interval_->mode == WaitInterval::THROTTLED; | 903 wait_interval_->mode == WaitInterval::THROTTLED; |
| 892 } | 904 } |
| 893 | 905 |
| 894 void SyncSchedulerImpl::OnReceivedShortPollIntervalUpdate( | 906 void SyncSchedulerImpl::OnReceivedShortPollIntervalUpdate( |
| 895 const base::TimeDelta& new_interval) { | 907 const TimeDelta& new_interval) { |
| 896 DCHECK(CalledOnValidThread()); | 908 DCHECK(CalledOnValidThread()); |
| 897 if (new_interval == syncer_short_poll_interval_seconds_) | 909 if (new_interval == syncer_short_poll_interval_seconds_) |
| 898 return; | 910 return; |
| 899 SDVLOG(1) << "Updating short poll interval to " << new_interval.InMinutes() | 911 SDVLOG(1) << "Updating short poll interval to " << new_interval.InMinutes() |
| 900 << " minutes."; | 912 << " minutes."; |
| 901 syncer_short_poll_interval_seconds_ = new_interval; | 913 syncer_short_poll_interval_seconds_ = new_interval; |
| 902 AdjustPolling(UPDATE_INTERVAL); | 914 AdjustPolling(UPDATE_INTERVAL); |
| 903 } | 915 } |
| 904 | 916 |
| 905 void SyncSchedulerImpl::OnReceivedLongPollIntervalUpdate( | 917 void SyncSchedulerImpl::OnReceivedLongPollIntervalUpdate( |
| 906 const base::TimeDelta& new_interval) { | 918 const TimeDelta& new_interval) { |
| 907 DCHECK(CalledOnValidThread()); | 919 DCHECK(CalledOnValidThread()); |
| 908 if (new_interval == syncer_long_poll_interval_seconds_) | 920 if (new_interval == syncer_long_poll_interval_seconds_) |
| 909 return; | 921 return; |
| 910 SDVLOG(1) << "Updating long poll interval to " << new_interval.InMinutes() | 922 SDVLOG(1) << "Updating long poll interval to " << new_interval.InMinutes() |
| 911 << " minutes."; | 923 << " minutes."; |
| 912 syncer_long_poll_interval_seconds_ = new_interval; | 924 syncer_long_poll_interval_seconds_ = new_interval; |
| 913 AdjustPolling(UPDATE_INTERVAL); | 925 AdjustPolling(UPDATE_INTERVAL); |
| 914 } | 926 } |
| 915 | 927 |
| 916 void SyncSchedulerImpl::OnReceivedCustomNudgeDelays( | 928 void SyncSchedulerImpl::OnReceivedCustomNudgeDelays( |
| 917 const std::map<ModelType, base::TimeDelta>& nudge_delays) { | 929 const std::map<ModelType, TimeDelta>& nudge_delays) { |
| 918 DCHECK(CalledOnValidThread()); | 930 DCHECK(CalledOnValidThread()); |
| 919 nudge_tracker_.OnReceivedCustomNudgeDelays(nudge_delays); | 931 nudge_tracker_.OnReceivedCustomNudgeDelays(nudge_delays); |
| 920 } | 932 } |
| 921 | 933 |
| 922 void SyncSchedulerImpl::OnReceivedClientInvalidationHintBufferSize(int size) { | 934 void SyncSchedulerImpl::OnReceivedClientInvalidationHintBufferSize(int size) { |
| 923 if (size > 0) | 935 if (size > 0) |
| 924 nudge_tracker_.SetHintBufferSize(size); | 936 nudge_tracker_.SetHintBufferSize(size); |
| 925 else | 937 else |
| 926 NOTREACHED() << "Hint buffer size should be > 0."; | 938 NOTREACHED() << "Hint buffer size should be > 0."; |
| 927 } | 939 } |
| 928 | 940 |
| 929 void SyncSchedulerImpl::OnSyncProtocolError( | 941 void SyncSchedulerImpl::OnSyncProtocolError( |
| 930 const SyncProtocolError& sync_protocol_error) { | 942 const SyncProtocolError& sync_protocol_error) { |
| 931 DCHECK(CalledOnValidThread()); | 943 DCHECK(CalledOnValidThread()); |
| 932 if (ShouldRequestEarlyExit(sync_protocol_error)) { | 944 if (ShouldRequestEarlyExit(sync_protocol_error)) { |
| 933 SDVLOG(2) << "Sync Scheduler requesting early exit."; | 945 SDVLOG(2) << "Sync Scheduler requesting early exit."; |
| 934 Stop(); | 946 Stop(); |
| 935 } | 947 } |
| 936 if (IsActionableError(sync_protocol_error)) { | 948 if (IsActionableError(sync_protocol_error)) { |
| 937 SDVLOG(2) << "OnActionableError"; | 949 SDVLOG(2) << "OnActionableError"; |
| 938 for (auto& observer : *cycle_context_->listeners()) | 950 for (auto& observer : *cycle_context_->listeners()) |
| 939 observer.OnActionableError(sync_protocol_error); | 951 observer.OnActionableError(sync_protocol_error); |
| 940 } | 952 } |
| 941 } | 953 } |
| 942 | 954 |
| 943 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const base::TimeDelta& delay) { | 955 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const TimeDelta& delay) { |
| 944 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + delay); | 956 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + delay); |
| 945 retry_timer_.Start(FROM_HERE, delay, this, | 957 retry_timer_.Start(FROM_HERE, delay, this, |
| 946 &SyncSchedulerImpl::RetryTimerCallback); | 958 &SyncSchedulerImpl::RetryTimerCallback); |
| 947 } | 959 } |
| 948 | 960 |
| 949 void SyncSchedulerImpl::OnReceivedMigrationRequest(ModelTypeSet types) { | 961 void SyncSchedulerImpl::OnReceivedMigrationRequest(ModelTypeSet types) { |
| 950 for (auto& observer : *cycle_context_->listeners()) | 962 for (auto& observer : *cycle_context_->listeners()) |
| 951 observer.OnMigrationRequested(types); | 963 observer.OnMigrationRequested(types); |
| 952 } | 964 } |
| 953 | 965 |
| 954 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { | 966 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { |
| 955 DCHECK(CalledOnValidThread()); | 967 DCHECK(CalledOnValidThread()); |
| 956 cycle_context_->set_notifications_enabled(notifications_enabled); | 968 cycle_context_->set_notifications_enabled(notifications_enabled); |
| 957 if (notifications_enabled) | 969 if (notifications_enabled) |
| 958 nudge_tracker_.OnInvalidationsEnabled(); | 970 nudge_tracker_.OnInvalidationsEnabled(); |
| 959 else | 971 else |
| 960 nudge_tracker_.OnInvalidationsDisabled(); | 972 nudge_tracker_.OnInvalidationsDisabled(); |
| 961 } | 973 } |
| 962 | 974 |
| 963 #undef SDVLOG_LOC | 975 #undef SDVLOG_LOC |
| 964 | 976 |
| 965 #undef SDVLOG | 977 #undef SDVLOG |
| 966 | 978 |
| 967 #undef SLOG | 979 #undef SLOG |
| 968 | 980 |
| 969 #undef ENUM_CASE | 981 #undef ENUM_CASE |
| 970 | 982 |
| 971 } // namespace syncer | 983 } // namespace syncer |
| OLD | NEW |