| 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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)), | 141 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)), |
| 142 mode_(CONFIGURATION_MODE), | 142 mode_(CONFIGURATION_MODE), |
| 143 delay_provider_(delay_provider), | 143 delay_provider_(delay_provider), |
| 144 syncer_(syncer), | 144 syncer_(syncer), |
| 145 cycle_context_(context), | 145 cycle_context_(context), |
| 146 next_sync_cycle_job_priority_(NORMAL_PRIORITY), | 146 next_sync_cycle_job_priority_(NORMAL_PRIORITY), |
| 147 ignore_auth_credentials_(ignore_auth_credentials), | 147 ignore_auth_credentials_(ignore_auth_credentials), |
| 148 weak_ptr_factory_(this) {} | 148 weak_ptr_factory_(this) {} |
| 149 | 149 |
| 150 SyncSchedulerImpl::~SyncSchedulerImpl() { | 150 SyncSchedulerImpl::~SyncSchedulerImpl() { |
| 151 DCHECK(CalledOnValidThread()); | 151 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 152 | 152 |
| 153 Stop(); | 153 Stop(); |
| 154 } | 154 } |
| 155 | 155 |
| 156 void SyncSchedulerImpl::OnCredentialsUpdated() { | 156 void SyncSchedulerImpl::OnCredentialsUpdated() { |
| 157 DCHECK(CalledOnValidThread()); | 157 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 158 | 158 |
| 159 if (HttpResponse::SYNC_AUTH_ERROR == | 159 if (HttpResponse::SYNC_AUTH_ERROR == |
| 160 cycle_context_->connection_manager()->server_status()) { | 160 cycle_context_->connection_manager()->server_status()) { |
| 161 OnServerConnectionErrorFixed(); | 161 OnServerConnectionErrorFixed(); |
| 162 } | 162 } |
| 163 } | 163 } |
| 164 | 164 |
| 165 void SyncSchedulerImpl::OnConnectionStatusChange() { | 165 void SyncSchedulerImpl::OnConnectionStatusChange() { |
| 166 DCHECK(CalledOnValidThread()); | 166 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 167 | 167 |
| 168 if (HttpResponse::CONNECTION_UNAVAILABLE == | 168 if (HttpResponse::CONNECTION_UNAVAILABLE == |
| 169 cycle_context_->connection_manager()->server_status()) { | 169 cycle_context_->connection_manager()->server_status()) { |
| 170 // Optimistically assume that the connection is fixed and try | 170 // Optimistically assume that the connection is fixed and try |
| 171 // connecting. | 171 // connecting. |
| 172 OnServerConnectionErrorFixed(); | 172 OnServerConnectionErrorFixed(); |
| 173 } | 173 } |
| 174 } | 174 } |
| 175 | 175 |
| 176 void SyncSchedulerImpl::OnServerConnectionErrorFixed() { | 176 void SyncSchedulerImpl::OnServerConnectionErrorFixed() { |
| 177 // There could be a pending nudge or configuration job in several cases: | 177 // There could be a pending nudge or configuration job in several cases: |
| 178 // | 178 // |
| 179 // 1. We're in exponential backoff. | 179 // 1. We're in exponential backoff. |
| 180 // 2. We're silenced / throttled. | 180 // 2. We're silenced / throttled. |
| 181 // 3. A nudge was saved previously due to not having a valid auth token. | 181 // 3. A nudge was saved previously due to not having a valid auth token. |
| 182 // 4. A nudge was scheduled + saved while in configuration mode. | 182 // 4. A nudge was scheduled + saved while in configuration mode. |
| 183 // | 183 // |
| 184 // In all cases except (2), we want to retry contacting the server. We | 184 // In all cases except (2), we want to retry contacting the server. We |
| 185 // call TryCanaryJob to achieve this, and note that nothing -- not even a | 185 // call TryCanaryJob to achieve this, and note that nothing -- not even a |
| 186 // canary job -- can bypass a THROTTLED WaitInterval. The only thing that | 186 // canary job -- can bypass a THROTTLED WaitInterval. The only thing that |
| 187 // has the authority to do that is the Unthrottle timer. | 187 // has the authority to do that is the Unthrottle timer. |
| 188 TryCanaryJob(); | 188 TryCanaryJob(); |
| 189 } | 189 } |
| 190 | 190 |
| 191 void SyncSchedulerImpl::Start(Mode mode, base::Time last_poll_time) { | 191 void SyncSchedulerImpl::Start(Mode mode, base::Time last_poll_time) { |
| 192 DCHECK(CalledOnValidThread()); | 192 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 193 | 193 |
| 194 std::string thread_name = base::PlatformThread::GetName(); | 194 std::string thread_name = base::PlatformThread::GetName(); |
| 195 if (thread_name.empty()) | 195 if (thread_name.empty()) |
| 196 thread_name = "<Main thread>"; | 196 thread_name = "<Main thread>"; |
| 197 SDVLOG(2) << "Start called from thread " << thread_name << " with mode " | 197 SDVLOG(2) << "Start called from thread " << thread_name << " with mode " |
| 198 << GetModeString(mode); | 198 << GetModeString(mode); |
| 199 if (!started_) { | 199 if (!started_) { |
| 200 started_ = true; | 200 started_ = true; |
| 201 SendInitialSnapshot(); | 201 SendInitialSnapshot(); |
| 202 } | 202 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 | 235 |
| 236 ModelTypeSet SyncSchedulerImpl::GetEnabledAndUnblockedTypes() { | 236 ModelTypeSet SyncSchedulerImpl::GetEnabledAndUnblockedTypes() { |
| 237 ModelTypeSet enabled_types = cycle_context_->GetEnabledTypes(); | 237 ModelTypeSet enabled_types = cycle_context_->GetEnabledTypes(); |
| 238 ModelTypeSet enabled_protocol_types = | 238 ModelTypeSet enabled_protocol_types = |
| 239 Intersection(ProtocolTypes(), enabled_types); | 239 Intersection(ProtocolTypes(), enabled_types); |
| 240 ModelTypeSet blocked_types = nudge_tracker_.GetBlockedTypes(); | 240 ModelTypeSet blocked_types = nudge_tracker_.GetBlockedTypes(); |
| 241 return Difference(enabled_protocol_types, blocked_types); | 241 return Difference(enabled_protocol_types, blocked_types); |
| 242 } | 242 } |
| 243 | 243 |
| 244 void SyncSchedulerImpl::SendInitialSnapshot() { | 244 void SyncSchedulerImpl::SendInitialSnapshot() { |
| 245 DCHECK(CalledOnValidThread()); | 245 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 246 | 246 |
| 247 SyncCycleEvent event(SyncCycleEvent::STATUS_CHANGED); | 247 SyncCycleEvent event(SyncCycleEvent::STATUS_CHANGED); |
| 248 event.snapshot = SyncCycle(cycle_context_, this).TakeSnapshot(); | 248 event.snapshot = SyncCycle(cycle_context_, this).TakeSnapshot(); |
| 249 for (auto& observer : *cycle_context_->listeners()) | 249 for (auto& observer : *cycle_context_->listeners()) |
| 250 observer.OnSyncCycleEvent(event); | 250 observer.OnSyncCycleEvent(event); |
| 251 } | 251 } |
| 252 | 252 |
| 253 void SyncSchedulerImpl::ScheduleConfiguration( | 253 void SyncSchedulerImpl::ScheduleConfiguration( |
| 254 const ConfigurationParams& params) { | 254 const ConfigurationParams& params) { |
| 255 DCHECK(CalledOnValidThread()); | 255 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 256 DCHECK(IsConfigRelatedUpdateSourceValue(params.source)); | 256 DCHECK(IsConfigRelatedUpdateSourceValue(params.source)); |
| 257 DCHECK_EQ(CONFIGURATION_MODE, mode_); | 257 DCHECK_EQ(CONFIGURATION_MODE, mode_); |
| 258 DCHECK(!params.ready_task.is_null()); | 258 DCHECK(!params.ready_task.is_null()); |
| 259 CHECK(started_) << "Scheduler must be running to configure."; | 259 CHECK(started_) << "Scheduler must be running to configure."; |
| 260 SDVLOG(2) << "Reconfiguring syncer."; | 260 SDVLOG(2) << "Reconfiguring syncer."; |
| 261 | 261 |
| 262 // Only one configuration is allowed at a time. Verify we're not waiting | 262 // Only one configuration is allowed at a time. Verify we're not waiting |
| 263 // for a pending configure job. | 263 // for a pending configure job. |
| 264 DCHECK(!pending_configure_params_); | 264 DCHECK(!pending_configure_params_); |
| 265 | 265 |
| 266 // Only reconfigure if we have types to download. | 266 // Only reconfigure if we have types to download. |
| 267 if (!params.types_to_download.Empty()) { | 267 if (!params.types_to_download.Empty()) { |
| 268 pending_configure_params_ = base::MakeUnique<ConfigurationParams>(params); | 268 pending_configure_params_ = base::MakeUnique<ConfigurationParams>(params); |
| 269 TrySyncCycleJob(); | 269 TrySyncCycleJob(); |
| 270 } else { | 270 } else { |
| 271 SDVLOG(2) << "No change in routing info, calling ready task directly."; | 271 SDVLOG(2) << "No change in routing info, calling ready task directly."; |
| 272 params.ready_task.Run(); | 272 params.ready_task.Run(); |
| 273 } | 273 } |
| 274 } | 274 } |
| 275 | 275 |
| 276 void SyncSchedulerImpl::ScheduleClearServerData(const ClearParams& params) { | 276 void SyncSchedulerImpl::ScheduleClearServerData(const ClearParams& params) { |
| 277 DCHECK(CalledOnValidThread()); | 277 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 278 DCHECK_EQ(CLEAR_SERVER_DATA_MODE, mode_); | 278 DCHECK_EQ(CLEAR_SERVER_DATA_MODE, mode_); |
| 279 DCHECK(!pending_configure_params_); | 279 DCHECK(!pending_configure_params_); |
| 280 DCHECK(!params.report_success_task.is_null()); | 280 DCHECK(!params.report_success_task.is_null()); |
| 281 CHECK(started_) << "Scheduler must be running to clear."; | 281 CHECK(started_) << "Scheduler must be running to clear."; |
| 282 | 282 |
| 283 pending_clear_params_ = base::MakeUnique<ClearParams>(params); | 283 pending_clear_params_ = base::MakeUnique<ClearParams>(params); |
| 284 TrySyncCycleJob(); | 284 TrySyncCycleJob(); |
| 285 } | 285 } |
| 286 | 286 |
| 287 bool SyncSchedulerImpl::CanRunJobNow(JobPriority priority) { | 287 bool SyncSchedulerImpl::CanRunJobNow(JobPriority priority) { |
| 288 DCHECK(CalledOnValidThread()); | 288 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 289 | 289 |
| 290 if (IsCurrentlyThrottled()) { | 290 if (IsCurrentlyThrottled()) { |
| 291 SDVLOG(1) << "Unable to run a job because we're throttled."; | 291 SDVLOG(1) << "Unable to run a job because we're throttled."; |
| 292 return false; | 292 return false; |
| 293 } | 293 } |
| 294 | 294 |
| 295 if (IsBackingOff() && priority != CANARY_PRIORITY) { | 295 if (IsBackingOff() && priority != CANARY_PRIORITY) { |
| 296 SDVLOG(1) << "Unable to run a job because we're backing off."; | 296 SDVLOG(1) << "Unable to run a job because we're backing off."; |
| 297 return false; | 297 return false; |
| 298 } | 298 } |
| 299 | 299 |
| 300 if (!ignore_auth_credentials_ && | 300 if (!ignore_auth_credentials_ && |
| 301 cycle_context_->connection_manager()->HasInvalidAuthToken()) { | 301 cycle_context_->connection_manager()->HasInvalidAuthToken()) { |
| 302 SDVLOG(1) << "Unable to run a job because we have no valid auth token."; | 302 SDVLOG(1) << "Unable to run a job because we have no valid auth token."; |
| 303 return false; | 303 return false; |
| 304 } | 304 } |
| 305 | 305 |
| 306 return true; | 306 return true; |
| 307 } | 307 } |
| 308 | 308 |
| 309 bool SyncSchedulerImpl::CanRunNudgeJobNow(JobPriority priority) { | 309 bool SyncSchedulerImpl::CanRunNudgeJobNow(JobPriority priority) { |
| 310 DCHECK(CalledOnValidThread()); | 310 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 311 | 311 |
| 312 if (!CanRunJobNow(priority)) { | 312 if (!CanRunJobNow(priority)) { |
| 313 SDVLOG(1) << "Unable to run a nudge job right now"; | 313 SDVLOG(1) << "Unable to run a nudge job right now"; |
| 314 return false; | 314 return false; |
| 315 } | 315 } |
| 316 | 316 |
| 317 const ModelTypeSet enabled_types = cycle_context_->GetEnabledTypes(); | 317 const ModelTypeSet enabled_types = cycle_context_->GetEnabledTypes(); |
| 318 if (nudge_tracker_.GetBlockedTypes().HasAll(enabled_types)) { | 318 if (nudge_tracker_.GetBlockedTypes().HasAll(enabled_types)) { |
| 319 SDVLOG(1) << "Not running a nudge because we're fully type throttled or " | 319 SDVLOG(1) << "Not running a nudge because we're fully type throttled or " |
| 320 "backed off."; | 320 "backed off."; |
| 321 return false; | 321 return false; |
| 322 } | 322 } |
| 323 | 323 |
| 324 if (mode_ != NORMAL_MODE) { | 324 if (mode_ != NORMAL_MODE) { |
| 325 SDVLOG(1) << "Not running nudge because we're not in normal mode."; | 325 SDVLOG(1) << "Not running nudge because we're not in normal mode."; |
| 326 return false; | 326 return false; |
| 327 } | 327 } |
| 328 | 328 |
| 329 return true; | 329 return true; |
| 330 } | 330 } |
| 331 | 331 |
| 332 void SyncSchedulerImpl::ScheduleLocalNudge( | 332 void SyncSchedulerImpl::ScheduleLocalNudge( |
| 333 ModelTypeSet types, | 333 ModelTypeSet types, |
| 334 const tracked_objects::Location& nudge_location) { | 334 const tracked_objects::Location& nudge_location) { |
| 335 DCHECK(CalledOnValidThread()); | 335 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 336 DCHECK(!types.Empty()); | 336 DCHECK(!types.Empty()); |
| 337 | 337 |
| 338 SDVLOG_LOC(nudge_location, 2) << "Scheduling sync because of local change to " | 338 SDVLOG_LOC(nudge_location, 2) << "Scheduling sync because of local change to " |
| 339 << ModelTypeSetToString(types); | 339 << ModelTypeSetToString(types); |
| 340 UpdateNudgeTimeRecords(types); | 340 UpdateNudgeTimeRecords(types); |
| 341 TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(types); | 341 TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(types); |
| 342 ScheduleNudgeImpl(nudge_delay, nudge_location); | 342 ScheduleNudgeImpl(nudge_delay, nudge_location); |
| 343 } | 343 } |
| 344 | 344 |
| 345 void SyncSchedulerImpl::ScheduleLocalRefreshRequest( | 345 void SyncSchedulerImpl::ScheduleLocalRefreshRequest( |
| 346 ModelTypeSet types, | 346 ModelTypeSet types, |
| 347 const tracked_objects::Location& nudge_location) { | 347 const tracked_objects::Location& nudge_location) { |
| 348 DCHECK(CalledOnValidThread()); | 348 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 349 DCHECK(!types.Empty()); | 349 DCHECK(!types.Empty()); |
| 350 | 350 |
| 351 SDVLOG_LOC(nudge_location, 2) | 351 SDVLOG_LOC(nudge_location, 2) |
| 352 << "Scheduling sync because of local refresh request for " | 352 << "Scheduling sync because of local refresh request for " |
| 353 << ModelTypeSetToString(types); | 353 << ModelTypeSetToString(types); |
| 354 TimeDelta nudge_delay = nudge_tracker_.RecordLocalRefreshRequest(types); | 354 TimeDelta nudge_delay = nudge_tracker_.RecordLocalRefreshRequest(types); |
| 355 ScheduleNudgeImpl(nudge_delay, nudge_location); | 355 ScheduleNudgeImpl(nudge_delay, nudge_location); |
| 356 } | 356 } |
| 357 | 357 |
| 358 void SyncSchedulerImpl::ScheduleInvalidationNudge( | 358 void SyncSchedulerImpl::ScheduleInvalidationNudge( |
| 359 ModelType model_type, | 359 ModelType model_type, |
| 360 std::unique_ptr<InvalidationInterface> invalidation, | 360 std::unique_ptr<InvalidationInterface> invalidation, |
| 361 const tracked_objects::Location& nudge_location) { | 361 const tracked_objects::Location& nudge_location) { |
| 362 DCHECK(CalledOnValidThread()); | 362 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 363 | 363 |
| 364 SDVLOG_LOC(nudge_location, 2) | 364 SDVLOG_LOC(nudge_location, 2) |
| 365 << "Scheduling sync because we received invalidation for " | 365 << "Scheduling sync because we received invalidation for " |
| 366 << ModelTypeToString(model_type); | 366 << ModelTypeToString(model_type); |
| 367 TimeDelta nudge_delay = nudge_tracker_.RecordRemoteInvalidation( | 367 TimeDelta nudge_delay = nudge_tracker_.RecordRemoteInvalidation( |
| 368 model_type, std::move(invalidation)); | 368 model_type, std::move(invalidation)); |
| 369 ScheduleNudgeImpl(nudge_delay, nudge_location); | 369 ScheduleNudgeImpl(nudge_delay, nudge_location); |
| 370 } | 370 } |
| 371 | 371 |
| 372 void SyncSchedulerImpl::ScheduleInitialSyncNudge(ModelType model_type) { | 372 void SyncSchedulerImpl::ScheduleInitialSyncNudge(ModelType model_type) { |
| 373 DCHECK(CalledOnValidThread()); | 373 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 374 | 374 |
| 375 SDVLOG(2) << "Scheduling non-blocking initial sync for " | 375 SDVLOG(2) << "Scheduling non-blocking initial sync for " |
| 376 << ModelTypeToString(model_type); | 376 << ModelTypeToString(model_type); |
| 377 nudge_tracker_.RecordInitialSyncRequired(model_type); | 377 nudge_tracker_.RecordInitialSyncRequired(model_type); |
| 378 ScheduleNudgeImpl(TimeDelta::FromSeconds(0), FROM_HERE); | 378 ScheduleNudgeImpl(TimeDelta::FromSeconds(0), FROM_HERE); |
| 379 } | 379 } |
| 380 | 380 |
| 381 // TODO(zea): Consider adding separate throttling/backoff for datatype | 381 // TODO(zea): Consider adding separate throttling/backoff for datatype |
| 382 // refresh requests. | 382 // refresh requests. |
| 383 void SyncSchedulerImpl::ScheduleNudgeImpl( | 383 void SyncSchedulerImpl::ScheduleNudgeImpl( |
| 384 const TimeDelta& delay, | 384 const TimeDelta& delay, |
| 385 const tracked_objects::Location& nudge_location) { | 385 const tracked_objects::Location& nudge_location) { |
| 386 DCHECK(CalledOnValidThread()); | 386 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 387 CHECK(!syncer_->IsSyncing()); | 387 CHECK(!syncer_->IsSyncing()); |
| 388 | 388 |
| 389 if (!started_) { | 389 if (!started_) { |
| 390 SDVLOG_LOC(nudge_location, 2) | 390 SDVLOG_LOC(nudge_location, 2) |
| 391 << "Dropping nudge, scheduler is not running."; | 391 << "Dropping nudge, scheduler is not running."; |
| 392 return; | 392 return; |
| 393 } | 393 } |
| 394 | 394 |
| 395 SDVLOG_LOC(nudge_location, 2) << "In ScheduleNudgeImpl with delay " | 395 SDVLOG_LOC(nudge_location, 2) << "In ScheduleNudgeImpl with delay " |
| 396 << delay.InMilliseconds() << " ms"; | 396 << delay.InMilliseconds() << " ms"; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 416 const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) { | 416 const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) { |
| 417 switch (mode) { | 417 switch (mode) { |
| 418 ENUM_CASE(CONFIGURATION_MODE); | 418 ENUM_CASE(CONFIGURATION_MODE); |
| 419 ENUM_CASE(CLEAR_SERVER_DATA_MODE); | 419 ENUM_CASE(CLEAR_SERVER_DATA_MODE); |
| 420 ENUM_CASE(NORMAL_MODE); | 420 ENUM_CASE(NORMAL_MODE); |
| 421 } | 421 } |
| 422 return ""; | 422 return ""; |
| 423 } | 423 } |
| 424 | 424 |
| 425 void SyncSchedulerImpl::SetDefaultNudgeDelay(TimeDelta delay_ms) { | 425 void SyncSchedulerImpl::SetDefaultNudgeDelay(TimeDelta delay_ms) { |
| 426 DCHECK(CalledOnValidThread()); | 426 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 427 | 427 |
| 428 nudge_tracker_.SetDefaultNudgeDelay(delay_ms); | 428 nudge_tracker_.SetDefaultNudgeDelay(delay_ms); |
| 429 } | 429 } |
| 430 | 430 |
| 431 void SyncSchedulerImpl::DoNudgeSyncCycleJob(JobPriority priority) { | 431 void SyncSchedulerImpl::DoNudgeSyncCycleJob(JobPriority priority) { |
| 432 DCHECK(CalledOnValidThread()); | 432 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 433 DCHECK(CanRunNudgeJobNow(priority)); | 433 DCHECK(CanRunNudgeJobNow(priority)); |
| 434 | 434 |
| 435 DVLOG(2) << "Will run normal mode sync cycle with types " | 435 DVLOG(2) << "Will run normal mode sync cycle with types " |
| 436 << ModelTypeSetToString(GetEnabledAndUnblockedTypes()); | 436 << ModelTypeSetToString(GetEnabledAndUnblockedTypes()); |
| 437 SyncCycle cycle(cycle_context_, this); | 437 SyncCycle cycle(cycle_context_, this); |
| 438 bool success = syncer_->NormalSyncShare(GetEnabledAndUnblockedTypes(), | 438 bool success = syncer_->NormalSyncShare(GetEnabledAndUnblockedTypes(), |
| 439 &nudge_tracker_, &cycle); | 439 &nudge_tracker_, &cycle); |
| 440 | 440 |
| 441 if (success) { | 441 if (success) { |
| 442 // That cycle took care of any outstanding work we had. | 442 // That cycle took care of any outstanding work we had. |
| 443 SDVLOG(2) << "Nudge succeeded."; | 443 SDVLOG(2) << "Nudge succeeded."; |
| 444 nudge_tracker_.RecordSuccessfulSyncCycle(); | 444 nudge_tracker_.RecordSuccessfulSyncCycle(); |
| 445 HandleSuccess(); | 445 HandleSuccess(); |
| 446 | 446 |
| 447 // If this was a canary, we may need to restart the poll timer (the poll | 447 // If this was a canary, we may need to restart the poll timer (the poll |
| 448 // timer may have fired while the scheduler was in an error state, ignoring | 448 // timer may have fired while the scheduler was in an error state, ignoring |
| 449 // the poll). | 449 // the poll). |
| 450 if (!poll_timer_.IsRunning()) { | 450 if (!poll_timer_.IsRunning()) { |
| 451 SDVLOG(1) << "Canary succeeded, restarting polling."; | 451 SDVLOG(1) << "Canary succeeded, restarting polling."; |
| 452 AdjustPolling(UPDATE_INTERVAL); | 452 AdjustPolling(UPDATE_INTERVAL); |
| 453 } | 453 } |
| 454 } else { | 454 } else { |
| 455 HandleFailure(cycle.status_controller().model_neutral_state()); | 455 HandleFailure(cycle.status_controller().model_neutral_state()); |
| 456 } | 456 } |
| 457 } | 457 } |
| 458 | 458 |
| 459 void SyncSchedulerImpl::DoConfigurationSyncCycleJob(JobPriority priority) { | 459 void SyncSchedulerImpl::DoConfigurationSyncCycleJob(JobPriority priority) { |
| 460 DCHECK(CalledOnValidThread()); | 460 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 461 DCHECK_EQ(mode_, CONFIGURATION_MODE); | 461 DCHECK_EQ(mode_, CONFIGURATION_MODE); |
| 462 DCHECK(pending_configure_params_ != nullptr); | 462 DCHECK(pending_configure_params_ != nullptr); |
| 463 | 463 |
| 464 if (!CanRunJobNow(priority)) { | 464 if (!CanRunJobNow(priority)) { |
| 465 SDVLOG(2) << "Unable to run configure job right now."; | 465 SDVLOG(2) << "Unable to run configure job right now."; |
| 466 RunAndReset(&pending_configure_params_->retry_task); | 466 RunAndReset(&pending_configure_params_->retry_task); |
| 467 return; | 467 return; |
| 468 } | 468 } |
| 469 | 469 |
| 470 SDVLOG(2) << "Will run configure SyncShare with types " | 470 SDVLOG(2) << "Will run configure SyncShare with types " |
| (...skipping 12 matching lines...) Expand all Loading... |
| 483 } else { | 483 } else { |
| 484 HandleFailure(cycle.status_controller().model_neutral_state()); | 484 HandleFailure(cycle.status_controller().model_neutral_state()); |
| 485 // Sync cycle might receive response from server that causes scheduler to | 485 // Sync cycle might receive response from server that causes scheduler to |
| 486 // stop and draws pending_configure_params_ invalid. | 486 // stop and draws pending_configure_params_ invalid. |
| 487 if (started_) | 487 if (started_) |
| 488 RunAndReset(&pending_configure_params_->retry_task); | 488 RunAndReset(&pending_configure_params_->retry_task); |
| 489 } | 489 } |
| 490 } | 490 } |
| 491 | 491 |
| 492 void SyncSchedulerImpl::DoClearServerDataSyncCycleJob(JobPriority priority) { | 492 void SyncSchedulerImpl::DoClearServerDataSyncCycleJob(JobPriority priority) { |
| 493 DCHECK(CalledOnValidThread()); | 493 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 494 DCHECK_EQ(mode_, CLEAR_SERVER_DATA_MODE); | 494 DCHECK_EQ(mode_, CLEAR_SERVER_DATA_MODE); |
| 495 | 495 |
| 496 if (!CanRunJobNow(priority)) { | 496 if (!CanRunJobNow(priority)) { |
| 497 SDVLOG(2) << "Unable to run clear server data job right now."; | 497 SDVLOG(2) << "Unable to run clear server data job right now."; |
| 498 return; | 498 return; |
| 499 } | 499 } |
| 500 | 500 |
| 501 SyncCycle cycle(cycle_context_, this); | 501 SyncCycle cycle(cycle_context_, this); |
| 502 const bool success = syncer_->PostClearServerData(&cycle); | 502 const bool success = syncer_->PostClearServerData(&cycle); |
| 503 if (!success) { | 503 if (!success) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 // failure handling to retry with backoff. | 549 // failure handling to retry with backoff. |
| 550 if (success) { | 550 if (success) { |
| 551 AdjustPolling(FORCE_RESET); | 551 AdjustPolling(FORCE_RESET); |
| 552 HandleSuccess(); | 552 HandleSuccess(); |
| 553 } else { | 553 } else { |
| 554 HandleFailure(cycle.status_controller().model_neutral_state()); | 554 HandleFailure(cycle.status_controller().model_neutral_state()); |
| 555 } | 555 } |
| 556 } | 556 } |
| 557 | 557 |
| 558 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { | 558 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { |
| 559 DCHECK(CalledOnValidThread()); | 559 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 560 | 560 |
| 561 TimeTicks now = TimeTicks::Now(); | 561 TimeTicks now = TimeTicks::Now(); |
| 562 // Update timing information for how often datatypes are triggering nudges. | 562 // Update timing information for how often datatypes are triggering nudges. |
| 563 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { | 563 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { |
| 564 TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()]; | 564 TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()]; |
| 565 last_local_nudges_by_model_type_[iter.Get()] = now; | 565 last_local_nudges_by_model_type_[iter.Get()] = now; |
| 566 if (previous.is_null()) | 566 if (previous.is_null()) |
| 567 continue; | 567 continue; |
| 568 | 568 |
| 569 #define PER_DATA_TYPE_MACRO(type_str) \ | 569 #define PER_DATA_TYPE_MACRO(type_str) \ |
| 570 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); | 570 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); |
| 571 SYNC_DATA_TYPE_HISTOGRAM(iter.Get()); | 571 SYNC_DATA_TYPE_HISTOGRAM(iter.Get()); |
| 572 #undef PER_DATA_TYPE_MACRO | 572 #undef PER_DATA_TYPE_MACRO |
| 573 } | 573 } |
| 574 } | 574 } |
| 575 | 575 |
| 576 TimeDelta SyncSchedulerImpl::GetPollInterval() { | 576 TimeDelta SyncSchedulerImpl::GetPollInterval() { |
| 577 return (!cycle_context_->notifications_enabled() || | 577 return (!cycle_context_->notifications_enabled() || |
| 578 !cycle_context_->ShouldFetchUpdatesBeforeCommit()) | 578 !cycle_context_->ShouldFetchUpdatesBeforeCommit()) |
| 579 ? syncer_short_poll_interval_seconds_ | 579 ? syncer_short_poll_interval_seconds_ |
| 580 : syncer_long_poll_interval_seconds_; | 580 : syncer_long_poll_interval_seconds_; |
| 581 } | 581 } |
| 582 | 582 |
| 583 void SyncSchedulerImpl::AdjustPolling(PollAdjustType type) { | 583 void SyncSchedulerImpl::AdjustPolling(PollAdjustType type) { |
| 584 DCHECK(CalledOnValidThread()); | 584 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 585 | 585 |
| 586 if (!started_) | 586 if (!started_) |
| 587 return; | 587 return; |
| 588 | 588 |
| 589 TimeDelta poll_interval = GetPollInterval(); | 589 TimeDelta poll_interval = GetPollInterval(); |
| 590 TimeDelta poll_delay = poll_interval; | 590 TimeDelta poll_delay = poll_interval; |
| 591 const TimeTicks now = TimeTicks::Now(); | 591 const TimeTicks now = TimeTicks::Now(); |
| 592 | 592 |
| 593 if (type == UPDATE_INTERVAL) { | 593 if (type == UPDATE_INTERVAL) { |
| 594 if (!last_poll_reset_.is_null()) { | 594 if (!last_poll_reset_.is_null()) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 if (!IsEarlierThanCurrentPendingJob(time_until_next_unblock)) { | 656 if (!IsEarlierThanCurrentPendingJob(time_until_next_unblock)) { |
| 657 return; | 657 return; |
| 658 } | 658 } |
| 659 pending_wakeup_timer_.Start(FROM_HERE, time_until_next_unblock, | 659 pending_wakeup_timer_.Start(FROM_HERE, time_until_next_unblock, |
| 660 base::Bind(&SyncSchedulerImpl::OnTypesUnblocked, | 660 base::Bind(&SyncSchedulerImpl::OnTypesUnblocked, |
| 661 weak_ptr_factory_.GetWeakPtr())); | 661 weak_ptr_factory_.GetWeakPtr())); |
| 662 } | 662 } |
| 663 } | 663 } |
| 664 | 664 |
| 665 void SyncSchedulerImpl::Stop() { | 665 void SyncSchedulerImpl::Stop() { |
| 666 DCHECK(CalledOnValidThread()); | 666 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 667 SDVLOG(2) << "Stop called"; | 667 SDVLOG(2) << "Stop called"; |
| 668 | 668 |
| 669 // Kill any in-flight method calls. | 669 // Kill any in-flight method calls. |
| 670 weak_ptr_factory_.InvalidateWeakPtrs(); | 670 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 671 wait_interval_.reset(); | 671 wait_interval_.reset(); |
| 672 NotifyRetryTime(base::Time()); | 672 NotifyRetryTime(base::Time()); |
| 673 poll_timer_.Stop(); | 673 poll_timer_.Stop(); |
| 674 pending_wakeup_timer_.Stop(); | 674 pending_wakeup_timer_.Stop(); |
| 675 pending_configure_params_.reset(); | 675 pending_configure_params_.reset(); |
| 676 pending_clear_params_.reset(); | 676 pending_clear_params_.reset(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 688 | 688 |
| 689 void SyncSchedulerImpl::TrySyncCycleJob() { | 689 void SyncSchedulerImpl::TrySyncCycleJob() { |
| 690 // Post call to TrySyncCycleJobImpl on current thread. Later request for | 690 // Post call to TrySyncCycleJobImpl on current thread. Later request for |
| 691 // access token will be here. | 691 // access token will be here. |
| 692 base::ThreadTaskRunnerHandle::Get()->PostTask( | 692 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 693 FROM_HERE, base::Bind(&SyncSchedulerImpl::TrySyncCycleJobImpl, | 693 FROM_HERE, base::Bind(&SyncSchedulerImpl::TrySyncCycleJobImpl, |
| 694 weak_ptr_factory_.GetWeakPtr())); | 694 weak_ptr_factory_.GetWeakPtr())); |
| 695 } | 695 } |
| 696 | 696 |
| 697 void SyncSchedulerImpl::TrySyncCycleJobImpl() { | 697 void SyncSchedulerImpl::TrySyncCycleJobImpl() { |
| 698 DCHECK(CalledOnValidThread()); | 698 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 699 | 699 |
| 700 JobPriority priority = next_sync_cycle_job_priority_; | 700 JobPriority priority = next_sync_cycle_job_priority_; |
| 701 next_sync_cycle_job_priority_ = NORMAL_PRIORITY; | 701 next_sync_cycle_job_priority_ = NORMAL_PRIORITY; |
| 702 | 702 |
| 703 nudge_tracker_.SetSyncCycleStartTime(TimeTicks::Now()); | 703 nudge_tracker_.SetSyncCycleStartTime(TimeTicks::Now()); |
| 704 | 704 |
| 705 if (mode_ == CONFIGURATION_MODE) { | 705 if (mode_ == CONFIGURATION_MODE) { |
| 706 if (pending_configure_params_) { | 706 if (pending_configure_params_) { |
| 707 SDVLOG(2) << "Found pending configure job"; | 707 SDVLOG(2) << "Found pending configure job"; |
| 708 DoConfigurationSyncCycleJob(priority); | 708 DoConfigurationSyncCycleJob(priority); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 723 // We must be in an error state. Transitioning out of each of these | 723 // We must be in an error state. Transitioning out of each of these |
| 724 // error states should trigger a canary job. | 724 // error states should trigger a canary job. |
| 725 DCHECK(IsCurrentlyThrottled() || IsBackingOff() || | 725 DCHECK(IsCurrentlyThrottled() || IsBackingOff() || |
| 726 cycle_context_->connection_manager()->HasInvalidAuthToken()); | 726 cycle_context_->connection_manager()->HasInvalidAuthToken()); |
| 727 } | 727 } |
| 728 | 728 |
| 729 RestartWaiting(); | 729 RestartWaiting(); |
| 730 } | 730 } |
| 731 | 731 |
| 732 void SyncSchedulerImpl::PollTimerCallback() { | 732 void SyncSchedulerImpl::PollTimerCallback() { |
| 733 DCHECK(CalledOnValidThread()); | 733 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 734 CHECK(!syncer_->IsSyncing()); | 734 CHECK(!syncer_->IsSyncing()); |
| 735 | 735 |
| 736 TrySyncCycleJob(); | 736 TrySyncCycleJob(); |
| 737 } | 737 } |
| 738 | 738 |
| 739 void SyncSchedulerImpl::RetryTimerCallback() { | 739 void SyncSchedulerImpl::RetryTimerCallback() { |
| 740 TrySyncCycleJob(); | 740 TrySyncCycleJob(); |
| 741 } | 741 } |
| 742 | 742 |
| 743 void SyncSchedulerImpl::Unthrottle() { | 743 void SyncSchedulerImpl::Unthrottle() { |
| 744 DCHECK(CalledOnValidThread()); | 744 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 745 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode); | 745 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode); |
| 746 | 746 |
| 747 // We're no longer throttled, so clear the wait interval. | 747 // We're no longer throttled, so clear the wait interval. |
| 748 wait_interval_.reset(); | 748 wait_interval_.reset(); |
| 749 NotifyRetryTime(base::Time()); | 749 NotifyRetryTime(base::Time()); |
| 750 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); | 750 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); |
| 751 | 751 |
| 752 // We treat this as a 'canary' in the sense that it was originally scheduled | 752 // We treat this as a 'canary' in the sense that it was originally scheduled |
| 753 // to run some time ago, failed, and we now want to retry, versus a job that | 753 // to run some time ago, failed, and we now want to retry, versus a job that |
| 754 // was just created (e.g via ScheduleNudgeImpl). The main implication is | 754 // was just created (e.g via ScheduleNudgeImpl). The main implication is |
| 755 // that we're careful to update routing info (etc) with such potentially | 755 // that we're careful to update routing info (etc) with such potentially |
| 756 // stale canary jobs. | 756 // stale canary jobs. |
| 757 TryCanaryJob(); | 757 TryCanaryJob(); |
| 758 } | 758 } |
| 759 | 759 |
| 760 void SyncSchedulerImpl::OnTypesUnblocked() { | 760 void SyncSchedulerImpl::OnTypesUnblocked() { |
| 761 DCHECK(CalledOnValidThread()); | 761 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 762 | 762 |
| 763 nudge_tracker_.UpdateTypeThrottlingAndBackoffState(); | 763 nudge_tracker_.UpdateTypeThrottlingAndBackoffState(); |
| 764 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); | 764 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); |
| 765 | 765 |
| 766 // Maybe this is a good time to run a nudge job. Let's try it. | 766 // Maybe this is a good time to run a nudge job. Let's try it. |
| 767 // If not a good time, reschedule a new run. | 767 // If not a good time, reschedule a new run. |
| 768 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) | 768 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) |
| 769 TrySyncCycleJob(); | 769 TrySyncCycleJob(); |
| 770 else | 770 else |
| 771 RestartWaiting(); | 771 RestartWaiting(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 } | 807 } |
| 808 } | 808 } |
| 809 | 809 |
| 810 for (auto& observer : *cycle_context_->listeners()) { | 810 for (auto& observer : *cycle_context_->listeners()) { |
| 811 observer.OnThrottledTypesChanged(throttled_types); | 811 observer.OnThrottledTypesChanged(throttled_types); |
| 812 observer.OnBackedOffTypesChanged(backed_off_types); | 812 observer.OnBackedOffTypesChanged(backed_off_types); |
| 813 } | 813 } |
| 814 } | 814 } |
| 815 | 815 |
| 816 bool SyncSchedulerImpl::IsBackingOff() const { | 816 bool SyncSchedulerImpl::IsBackingOff() const { |
| 817 DCHECK(CalledOnValidThread()); | 817 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 818 | 818 |
| 819 return wait_interval_.get() && | 819 return wait_interval_.get() && |
| 820 wait_interval_->mode == WaitInterval::EXPONENTIAL_BACKOFF; | 820 wait_interval_->mode == WaitInterval::EXPONENTIAL_BACKOFF; |
| 821 } | 821 } |
| 822 | 822 |
| 823 void SyncSchedulerImpl::OnThrottled(const TimeDelta& throttle_duration) { | 823 void SyncSchedulerImpl::OnThrottled(const TimeDelta& throttle_duration) { |
| 824 DCHECK(CalledOnValidThread()); | 824 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 825 | 825 |
| 826 wait_interval_ = base::MakeUnique<WaitInterval>(WaitInterval::THROTTLED, | 826 wait_interval_ = base::MakeUnique<WaitInterval>(WaitInterval::THROTTLED, |
| 827 throttle_duration); | 827 throttle_duration); |
| 828 NotifyRetryTime(base::Time::Now() + wait_interval_->length); | 828 NotifyRetryTime(base::Time::Now() + wait_interval_->length); |
| 829 | 829 |
| 830 for (auto& observer : *cycle_context_->listeners()) { | 830 for (auto& observer : *cycle_context_->listeners()) { |
| 831 observer.OnThrottledTypesChanged(ModelTypeSet::All()); | 831 observer.OnThrottledTypesChanged(ModelTypeSet::All()); |
| 832 } | 832 } |
| 833 } | 833 } |
| 834 | 834 |
| 835 void SyncSchedulerImpl::OnTypesThrottled(ModelTypeSet types, | 835 void SyncSchedulerImpl::OnTypesThrottled(ModelTypeSet types, |
| 836 const TimeDelta& throttle_duration) { | 836 const TimeDelta& throttle_duration) { |
| 837 DCHECK(CalledOnValidThread()); | 837 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 838 | 838 |
| 839 TimeTicks now = TimeTicks::Now(); | 839 TimeTicks now = TimeTicks::Now(); |
| 840 | 840 |
| 841 SDVLOG(1) << "Throttling " << ModelTypeSetToString(types) << " for " | 841 SDVLOG(1) << "Throttling " << ModelTypeSetToString(types) << " for " |
| 842 << throttle_duration.InMinutes() << " minutes."; | 842 << throttle_duration.InMinutes() << " minutes."; |
| 843 | 843 |
| 844 nudge_tracker_.SetTypesThrottledUntil(types, throttle_duration, now); | 844 nudge_tracker_.SetTypesThrottledUntil(types, throttle_duration, now); |
| 845 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); | 845 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); |
| 846 } | 846 } |
| 847 | 847 |
| 848 void SyncSchedulerImpl::OnTypesBackedOff(ModelTypeSet types) { | 848 void SyncSchedulerImpl::OnTypesBackedOff(ModelTypeSet types) { |
| 849 DCHECK(CalledOnValidThread()); | 849 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 850 | 850 |
| 851 TimeTicks now = TimeTicks::Now(); | 851 TimeTicks now = TimeTicks::Now(); |
| 852 | 852 |
| 853 for (ModelTypeSet::Iterator type = types.First(); type.Good(); type.Inc()) { | 853 for (ModelTypeSet::Iterator type = types.First(); type.Good(); type.Inc()) { |
| 854 TimeDelta last_backoff_time = | 854 TimeDelta last_backoff_time = |
| 855 TimeDelta::FromSeconds(kInitialBackoffRetrySeconds); | 855 TimeDelta::FromSeconds(kInitialBackoffRetrySeconds); |
| 856 if (nudge_tracker_.GetTypeBlockingMode(type.Get()) == | 856 if (nudge_tracker_.GetTypeBlockingMode(type.Get()) == |
| 857 WaitInterval::EXPONENTIAL_BACKOFF_RETRYING) { | 857 WaitInterval::EXPONENTIAL_BACKOFF_RETRYING) { |
| 858 last_backoff_time = nudge_tracker_.GetTypeLastBackoffInterval(type.Get()); | 858 last_backoff_time = nudge_tracker_.GetTypeLastBackoffInterval(type.Get()); |
| 859 } | 859 } |
| 860 | 860 |
| 861 TimeDelta length = delay_provider_->GetDelay(last_backoff_time); | 861 TimeDelta length = delay_provider_->GetDelay(last_backoff_time); |
| 862 nudge_tracker_.SetTypeBackedOff(type.Get(), length, now); | 862 nudge_tracker_.SetTypeBackedOff(type.Get(), length, now); |
| 863 SDVLOG(1) << "Backing off " << ModelTypeToString(type.Get()) << " for " | 863 SDVLOG(1) << "Backing off " << ModelTypeToString(type.Get()) << " for " |
| 864 << length.InSeconds() << " second."; | 864 << length.InSeconds() << " second."; |
| 865 } | 865 } |
| 866 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); | 866 NotifyBlockedTypesChanged(nudge_tracker_.GetBlockedTypes()); |
| 867 } | 867 } |
| 868 | 868 |
| 869 bool SyncSchedulerImpl::IsCurrentlyThrottled() { | 869 bool SyncSchedulerImpl::IsCurrentlyThrottled() { |
| 870 DCHECK(CalledOnValidThread()); | 870 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 871 | 871 |
| 872 return wait_interval_.get() && | 872 return wait_interval_.get() && |
| 873 wait_interval_->mode == WaitInterval::THROTTLED; | 873 wait_interval_->mode == WaitInterval::THROTTLED; |
| 874 } | 874 } |
| 875 | 875 |
| 876 void SyncSchedulerImpl::OnReceivedShortPollIntervalUpdate( | 876 void SyncSchedulerImpl::OnReceivedShortPollIntervalUpdate( |
| 877 const TimeDelta& new_interval) { | 877 const TimeDelta& new_interval) { |
| 878 DCHECK(CalledOnValidThread()); | 878 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 879 | 879 |
| 880 if (new_interval == syncer_short_poll_interval_seconds_) | 880 if (new_interval == syncer_short_poll_interval_seconds_) |
| 881 return; | 881 return; |
| 882 SDVLOG(1) << "Updating short poll interval to " << new_interval.InMinutes() | 882 SDVLOG(1) << "Updating short poll interval to " << new_interval.InMinutes() |
| 883 << " minutes."; | 883 << " minutes."; |
| 884 syncer_short_poll_interval_seconds_ = new_interval; | 884 syncer_short_poll_interval_seconds_ = new_interval; |
| 885 AdjustPolling(UPDATE_INTERVAL); | 885 AdjustPolling(UPDATE_INTERVAL); |
| 886 } | 886 } |
| 887 | 887 |
| 888 void SyncSchedulerImpl::OnReceivedLongPollIntervalUpdate( | 888 void SyncSchedulerImpl::OnReceivedLongPollIntervalUpdate( |
| 889 const TimeDelta& new_interval) { | 889 const TimeDelta& new_interval) { |
| 890 DCHECK(CalledOnValidThread()); | 890 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 891 | 891 |
| 892 if (new_interval == syncer_long_poll_interval_seconds_) | 892 if (new_interval == syncer_long_poll_interval_seconds_) |
| 893 return; | 893 return; |
| 894 SDVLOG(1) << "Updating long poll interval to " << new_interval.InMinutes() | 894 SDVLOG(1) << "Updating long poll interval to " << new_interval.InMinutes() |
| 895 << " minutes."; | 895 << " minutes."; |
| 896 syncer_long_poll_interval_seconds_ = new_interval; | 896 syncer_long_poll_interval_seconds_ = new_interval; |
| 897 AdjustPolling(UPDATE_INTERVAL); | 897 AdjustPolling(UPDATE_INTERVAL); |
| 898 } | 898 } |
| 899 | 899 |
| 900 void SyncSchedulerImpl::OnReceivedCustomNudgeDelays( | 900 void SyncSchedulerImpl::OnReceivedCustomNudgeDelays( |
| 901 const std::map<ModelType, TimeDelta>& nudge_delays) { | 901 const std::map<ModelType, TimeDelta>& nudge_delays) { |
| 902 DCHECK(CalledOnValidThread()); | 902 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 903 | 903 |
| 904 nudge_tracker_.OnReceivedCustomNudgeDelays(nudge_delays); | 904 nudge_tracker_.OnReceivedCustomNudgeDelays(nudge_delays); |
| 905 } | 905 } |
| 906 | 906 |
| 907 void SyncSchedulerImpl::OnReceivedClientInvalidationHintBufferSize(int size) { | 907 void SyncSchedulerImpl::OnReceivedClientInvalidationHintBufferSize(int size) { |
| 908 DCHECK(CalledOnValidThread()); | 908 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 909 | 909 |
| 910 if (size > 0) | 910 if (size > 0) |
| 911 nudge_tracker_.SetHintBufferSize(size); | 911 nudge_tracker_.SetHintBufferSize(size); |
| 912 else | 912 else |
| 913 NOTREACHED() << "Hint buffer size should be > 0."; | 913 NOTREACHED() << "Hint buffer size should be > 0."; |
| 914 } | 914 } |
| 915 | 915 |
| 916 void SyncSchedulerImpl::OnSyncProtocolError( | 916 void SyncSchedulerImpl::OnSyncProtocolError( |
| 917 const SyncProtocolError& sync_protocol_error) { | 917 const SyncProtocolError& sync_protocol_error) { |
| 918 DCHECK(CalledOnValidThread()); | 918 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 919 | 919 |
| 920 if (ShouldRequestEarlyExit(sync_protocol_error)) { | 920 if (ShouldRequestEarlyExit(sync_protocol_error)) { |
| 921 SDVLOG(2) << "Sync Scheduler requesting early exit."; | 921 SDVLOG(2) << "Sync Scheduler requesting early exit."; |
| 922 Stop(); | 922 Stop(); |
| 923 } | 923 } |
| 924 if (IsActionableError(sync_protocol_error)) { | 924 if (IsActionableError(sync_protocol_error)) { |
| 925 SDVLOG(2) << "OnActionableError"; | 925 SDVLOG(2) << "OnActionableError"; |
| 926 for (auto& observer : *cycle_context_->listeners()) | 926 for (auto& observer : *cycle_context_->listeners()) |
| 927 observer.OnActionableError(sync_protocol_error); | 927 observer.OnActionableError(sync_protocol_error); |
| 928 } | 928 } |
| 929 } | 929 } |
| 930 | 930 |
| 931 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const TimeDelta& delay) { | 931 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const TimeDelta& delay) { |
| 932 DCHECK(CalledOnValidThread()); | 932 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 933 | 933 |
| 934 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + delay); | 934 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + delay); |
| 935 retry_timer_.Start(FROM_HERE, delay, this, | 935 retry_timer_.Start(FROM_HERE, delay, this, |
| 936 &SyncSchedulerImpl::RetryTimerCallback); | 936 &SyncSchedulerImpl::RetryTimerCallback); |
| 937 } | 937 } |
| 938 | 938 |
| 939 void SyncSchedulerImpl::OnReceivedMigrationRequest(ModelTypeSet types) { | 939 void SyncSchedulerImpl::OnReceivedMigrationRequest(ModelTypeSet types) { |
| 940 DCHECK(CalledOnValidThread()); | 940 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 941 | 941 |
| 942 for (auto& observer : *cycle_context_->listeners()) | 942 for (auto& observer : *cycle_context_->listeners()) |
| 943 observer.OnMigrationRequested(types); | 943 observer.OnMigrationRequested(types); |
| 944 } | 944 } |
| 945 | 945 |
| 946 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { | 946 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { |
| 947 DCHECK(CalledOnValidThread()); | 947 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 948 | 948 |
| 949 cycle_context_->set_notifications_enabled(notifications_enabled); | 949 cycle_context_->set_notifications_enabled(notifications_enabled); |
| 950 if (notifications_enabled) | 950 if (notifications_enabled) |
| 951 nudge_tracker_.OnInvalidationsEnabled(); | 951 nudge_tracker_.OnInvalidationsEnabled(); |
| 952 else | 952 else |
| 953 nudge_tracker_.OnInvalidationsDisabled(); | 953 nudge_tracker_.OnInvalidationsDisabled(); |
| 954 } | 954 } |
| 955 | 955 |
| 956 bool SyncSchedulerImpl::IsEarlierThanCurrentPendingJob(const TimeDelta& delay) { | 956 bool SyncSchedulerImpl::IsEarlierThanCurrentPendingJob(const TimeDelta& delay) { |
| 957 TimeTicks incoming_run_time = TimeTicks::Now() + delay; | 957 TimeTicks incoming_run_time = TimeTicks::Now() + delay; |
| 958 if (pending_wakeup_timer_.IsRunning() && | 958 if (pending_wakeup_timer_.IsRunning() && |
| 959 (pending_wakeup_timer_.desired_run_time() < incoming_run_time)) { | 959 (pending_wakeup_timer_.desired_run_time() < incoming_run_time)) { |
| 960 // Old job arrives sooner than this one. | 960 // Old job arrives sooner than this one. |
| 961 return false; | 961 return false; |
| 962 } | 962 } |
| 963 return true; | 963 return true; |
| 964 } | 964 } |
| 965 | 965 |
| 966 #undef SDVLOG_LOC | 966 #undef SDVLOG_LOC |
| 967 | 967 |
| 968 #undef SDVLOG | 968 #undef SDVLOG |
| 969 | 969 |
| 970 #undef SLOG | 970 #undef SLOG |
| 971 | 971 |
| 972 #undef ENUM_CASE | 972 #undef ENUM_CASE |
| 973 | 973 |
| 974 } // namespace syncer | 974 } // namespace syncer |
| OLD | NEW |