| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sync/engine/sync_scheduler_impl.h" | 5 #include "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 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 14 #include "base/location.h" | 14 #include "base/location.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
| 17 #include "base/threading/platform_thread.h" | 17 #include "base/threading/platform_thread.h" |
| 18 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 19 #include "sync/engine/backoff_delay_provider.h" | 19 #include "components/sync/base/data_type_histogram.h" |
| 20 #include "sync/engine/syncer.h" | 20 #include "components/sync/base/logging.h" |
| 21 #include "sync/protocol/proto_enum_conversions.h" | 21 #include "components/sync/engine_impl/backoff_delay_provider.h" |
| 22 #include "sync/protocol/sync.pb.h" | 22 #include "components/sync/engine_impl/syncer.h" |
| 23 #include "sync/util/data_type_histogram.h" | 23 #include "components/sync/protocol/proto_enum_conversions.h" |
| 24 #include "sync/util/logging.h" | 24 #include "components/sync/protocol/sync.pb.h" |
| 25 | 25 |
| 26 using base::TimeDelta; | 26 using base::TimeDelta; |
| 27 using base::TimeTicks; | 27 using base::TimeTicks; |
| 28 | 28 |
| 29 namespace syncer { | 29 namespace syncer { |
| 30 | 30 |
| 31 using sessions::SyncSession; | 31 using sessions::SyncSession; |
| 32 using sessions::SyncSessionSnapshot; | 32 using sessions::SyncSessionSnapshot; |
| 33 using sync_pb::GetUpdatesCallerInfo; | 33 using sync_pb::GetUpdatesCallerInfo; |
| 34 | 34 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 return true; | 72 return true; |
| 73 // Make UNKNOWN_ERROR a NOTREACHED. All the other error should be explicitly | 73 // Make UNKNOWN_ERROR a NOTREACHED. All the other error should be explicitly |
| 74 // handled. | 74 // handled. |
| 75 case UNKNOWN_ERROR: | 75 case UNKNOWN_ERROR: |
| 76 NOTREACHED(); | 76 NOTREACHED(); |
| 77 return false; | 77 return false; |
| 78 } | 78 } |
| 79 return false; | 79 return false; |
| 80 } | 80 } |
| 81 | 81 |
| 82 bool IsActionableError( | 82 bool IsActionableError(const SyncProtocolError& error) { |
| 83 const SyncProtocolError& error) { | |
| 84 return (error.action != UNKNOWN_ACTION); | 83 return (error.action != UNKNOWN_ACTION); |
| 85 } | 84 } |
| 86 | 85 |
| 87 void RunAndReset(base::Closure* task) { | 86 void RunAndReset(base::Closure* task) { |
| 88 DCHECK(task); | 87 DCHECK(task); |
| 89 if (task->is_null()) | 88 if (task->is_null()) |
| 90 return; | 89 return; |
| 91 task->Run(); | 90 task->Run(); |
| 92 task->Reset(); | 91 task->Reset(); |
| 93 } | 92 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 113 default; | 112 default; |
| 114 ConfigurationParams::~ConfigurationParams() {} | 113 ConfigurationParams::~ConfigurationParams() {} |
| 115 | 114 |
| 116 ClearParams::ClearParams(const base::Closure& report_success_task) | 115 ClearParams::ClearParams(const base::Closure& report_success_task) |
| 117 : report_success_task(report_success_task) { | 116 : report_success_task(report_success_task) { |
| 118 DCHECK(!report_success_task.is_null()); | 117 DCHECK(!report_success_task.is_null()); |
| 119 } | 118 } |
| 120 ClearParams::ClearParams(const ClearParams& other) = default; | 119 ClearParams::ClearParams(const ClearParams& other) = default; |
| 121 ClearParams::~ClearParams() {} | 120 ClearParams::~ClearParams() {} |
| 122 | 121 |
| 123 SyncSchedulerImpl::WaitInterval::WaitInterval() | 122 SyncSchedulerImpl::WaitInterval::WaitInterval() : mode(UNKNOWN) {} |
| 124 : mode(UNKNOWN) {} | |
| 125 | 123 |
| 126 SyncSchedulerImpl::WaitInterval::WaitInterval(Mode mode, TimeDelta length) | 124 SyncSchedulerImpl::WaitInterval::WaitInterval(Mode mode, TimeDelta length) |
| 127 : mode(mode), length(length) {} | 125 : mode(mode), length(length) {} |
| 128 | 126 |
| 129 SyncSchedulerImpl::WaitInterval::~WaitInterval() {} | 127 SyncSchedulerImpl::WaitInterval::~WaitInterval() {} |
| 130 | 128 |
| 131 #define ENUM_CASE(x) case x: return #x; break; | 129 #define ENUM_CASE(x) \ |
| 130 case x: \ |
| 131 return #x; \ |
| 132 break; |
| 132 | 133 |
| 133 const char* SyncSchedulerImpl::WaitInterval::GetModeString(Mode mode) { | 134 const char* SyncSchedulerImpl::WaitInterval::GetModeString(Mode mode) { |
| 134 switch (mode) { | 135 switch (mode) { |
| 135 ENUM_CASE(UNKNOWN); | 136 ENUM_CASE(UNKNOWN); |
| 136 ENUM_CASE(EXPONENTIAL_BACKOFF); | 137 ENUM_CASE(EXPONENTIAL_BACKOFF); |
| 137 ENUM_CASE(THROTTLED); | 138 ENUM_CASE(THROTTLED); |
| 138 } | 139 } |
| 139 NOTREACHED(); | 140 NOTREACHED(); |
| 140 return ""; | 141 return ""; |
| 141 } | 142 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 157 } | 158 } |
| 158 } | 159 } |
| 159 | 160 |
| 160 // Helper macros to log with the syncer thread name; useful when there | 161 // Helper macros to log with the syncer thread name; useful when there |
| 161 // are multiple syncer threads involved. | 162 // are multiple syncer threads involved. |
| 162 | 163 |
| 163 #define SLOG(severity) LOG(severity) << name_ << ": " | 164 #define SLOG(severity) LOG(severity) << name_ << ": " |
| 164 | 165 |
| 165 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " | 166 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " |
| 166 | 167 |
| 167 #define SDVLOG_LOC(from_here, verbose_level) \ | 168 #define SDVLOG_LOC(from_here, verbose_level) \ |
| 168 DVLOG_LOC(from_here, verbose_level) << name_ << ": " | 169 DVLOG_LOC(from_here, verbose_level) << name_ << ": " |
| 169 | 170 |
| 170 SyncSchedulerImpl::SyncSchedulerImpl(const std::string& name, | 171 SyncSchedulerImpl::SyncSchedulerImpl(const std::string& name, |
| 171 BackoffDelayProvider* delay_provider, | 172 BackoffDelayProvider* delay_provider, |
| 172 sessions::SyncSessionContext* context, | 173 sessions::SyncSessionContext* context, |
| 173 Syncer* syncer) | 174 Syncer* syncer) |
| 174 : name_(name), | 175 : name_(name), |
| 175 started_(false), | 176 started_(false), |
| 176 syncer_short_poll_interval_seconds_( | 177 syncer_short_poll_interval_seconds_( |
| 177 TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds)), | 178 TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds)), |
| 178 syncer_long_poll_interval_seconds_( | 179 syncer_long_poll_interval_seconds_( |
| 179 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)), | 180 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)), |
| 180 mode_(CONFIGURATION_MODE), | 181 mode_(CONFIGURATION_MODE), |
| 181 delay_provider_(delay_provider), | 182 delay_provider_(delay_provider), |
| 182 syncer_(syncer), | 183 syncer_(syncer), |
| 183 session_context_(context), | 184 session_context_(context), |
| 184 next_sync_session_job_priority_(NORMAL_PRIORITY), | 185 next_sync_session_job_priority_(NORMAL_PRIORITY), |
| 185 weak_ptr_factory_(this), | 186 weak_ptr_factory_(this), |
| 186 weak_ptr_factory_for_weak_handle_(this) { | 187 weak_ptr_factory_for_weak_handle_(this) { |
| 187 weak_handle_this_ = MakeWeakHandle( | 188 weak_handle_this_ = |
| 188 weak_ptr_factory_for_weak_handle_.GetWeakPtr()); | 189 MakeWeakHandle(weak_ptr_factory_for_weak_handle_.GetWeakPtr()); |
| 189 } | 190 } |
| 190 | 191 |
| 191 SyncSchedulerImpl::~SyncSchedulerImpl() { | 192 SyncSchedulerImpl::~SyncSchedulerImpl() { |
| 192 DCHECK(CalledOnValidThread()); | 193 DCHECK(CalledOnValidThread()); |
| 193 Stop(); | 194 Stop(); |
| 194 } | 195 } |
| 195 | 196 |
| 196 void SyncSchedulerImpl::OnCredentialsUpdated() { | 197 void SyncSchedulerImpl::OnCredentialsUpdated() { |
| 197 DCHECK(CalledOnValidThread()); | 198 DCHECK(CalledOnValidThread()); |
| 198 | 199 |
| 199 if (HttpResponse::SYNC_AUTH_ERROR == | 200 if (HttpResponse::SYNC_AUTH_ERROR == |
| 200 session_context_->connection_manager()->server_status()) { | 201 session_context_->connection_manager()->server_status()) { |
| 201 OnServerConnectionErrorFixed(); | 202 OnServerConnectionErrorFixed(); |
| 202 } | 203 } |
| 203 } | 204 } |
| 204 | 205 |
| 205 void SyncSchedulerImpl::OnConnectionStatusChange() { | 206 void SyncSchedulerImpl::OnConnectionStatusChange() { |
| 206 if (HttpResponse::CONNECTION_UNAVAILABLE == | 207 if (HttpResponse::CONNECTION_UNAVAILABLE == |
| 207 session_context_->connection_manager()->server_status()) { | 208 session_context_->connection_manager()->server_status()) { |
| 208 // Optimistically assume that the connection is fixed and try | 209 // Optimistically assume that the connection is fixed and try |
| 209 // connecting. | 210 // connecting. |
| 210 OnServerConnectionErrorFixed(); | 211 OnServerConnectionErrorFixed(); |
| 211 } | 212 } |
| 212 } | 213 } |
| 213 | 214 |
| 214 void SyncSchedulerImpl::OnServerConnectionErrorFixed() { | 215 void SyncSchedulerImpl::OnServerConnectionErrorFixed() { |
| 215 // There could be a pending nudge or configuration job in several cases: | 216 // There could be a pending nudge or configuration job in several cases: |
| 216 // | 217 // |
| 217 // 1. We're in exponential backoff. | 218 // 1. We're in exponential backoff. |
| 218 // 2. We're silenced / throttled. | 219 // 2. We're silenced / throttled. |
| 219 // 3. A nudge was saved previously due to not having a valid auth token. | 220 // 3. A nudge was saved previously due to not having a valid auth token. |
| 220 // 4. A nudge was scheduled + saved while in configuration mode. | 221 // 4. A nudge was scheduled + saved while in configuration mode. |
| 221 // | 222 // |
| 222 // In all cases except (2), we want to retry contacting the server. We | 223 // In all cases except (2), we want to retry contacting the server. We |
| 223 // call TryCanaryJob to achieve this, and note that nothing -- not even a | 224 // call TryCanaryJob to achieve this, and note that nothing -- not even a |
| 224 // canary job -- can bypass a THROTTLED WaitInterval. The only thing that | 225 // canary job -- can bypass a THROTTLED WaitInterval. The only thing that |
| 225 // has the authority to do that is the Unthrottle timer. | 226 // has the authority to do that is the Unthrottle timer. |
| 226 TryCanaryJob(); | 227 TryCanaryJob(); |
| 227 } | 228 } |
| 228 | 229 |
| 229 void SyncSchedulerImpl::Start(Mode mode, base::Time last_poll_time) { | 230 void SyncSchedulerImpl::Start(Mode mode, base::Time last_poll_time) { |
| 230 DCHECK(CalledOnValidThread()); | 231 DCHECK(CalledOnValidThread()); |
| 231 std::string thread_name = base::PlatformThread::GetName(); | 232 std::string thread_name = base::PlatformThread::GetName(); |
| 232 if (thread_name.empty()) | 233 if (thread_name.empty()) |
| 233 thread_name = "<Main thread>"; | 234 thread_name = "<Main thread>"; |
| 234 SDVLOG(2) << "Start called from thread " | 235 SDVLOG(2) << "Start called from thread " << thread_name << " with mode " |
| 235 << thread_name << " with mode " << GetModeString(mode); | 236 << GetModeString(mode); |
| 236 if (!started_) { | 237 if (!started_) { |
| 237 started_ = true; | 238 started_ = true; |
| 238 SendInitialSnapshot(); | 239 SendInitialSnapshot(); |
| 239 } | 240 } |
| 240 | 241 |
| 241 DCHECK(syncer_.get()); | 242 DCHECK(syncer_.get()); |
| 242 | 243 |
| 243 if (mode == CLEAR_SERVER_DATA_MODE) { | 244 if (mode == CLEAR_SERVER_DATA_MODE) { |
| 244 DCHECK_EQ(mode_, CONFIGURATION_MODE); | 245 DCHECK_EQ(mode_, CONFIGURATION_MODE); |
| 245 } | 246 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 ModelTypeSet throttled_types = nudge_tracker_.GetThrottledTypes(); | 279 ModelTypeSet throttled_types = nudge_tracker_.GetThrottledTypes(); |
| 279 return Difference(enabled_protocol_types, throttled_types); | 280 return Difference(enabled_protocol_types, throttled_types); |
| 280 } | 281 } |
| 281 | 282 |
| 282 void SyncSchedulerImpl::SendInitialSnapshot() { | 283 void SyncSchedulerImpl::SendInitialSnapshot() { |
| 283 DCHECK(CalledOnValidThread()); | 284 DCHECK(CalledOnValidThread()); |
| 284 std::unique_ptr<SyncSession> dummy( | 285 std::unique_ptr<SyncSession> dummy( |
| 285 SyncSession::Build(session_context_, this)); | 286 SyncSession::Build(session_context_, this)); |
| 286 SyncCycleEvent event(SyncCycleEvent::STATUS_CHANGED); | 287 SyncCycleEvent event(SyncCycleEvent::STATUS_CHANGED); |
| 287 event.snapshot = dummy->TakeSnapshot(); | 288 event.snapshot = dummy->TakeSnapshot(); |
| 288 FOR_EACH_OBSERVER(SyncEngineEventListener, | 289 FOR_EACH_OBSERVER(SyncEngineEventListener, *session_context_->listeners(), |
| 289 *session_context_->listeners(), | |
| 290 OnSyncCycleEvent(event)); | 290 OnSyncCycleEvent(event)); |
| 291 } | 291 } |
| 292 | 292 |
| 293 namespace { | 293 namespace { |
| 294 | 294 |
| 295 // Helper to extract the routing info corresponding to types in | 295 // Helper to extract the routing info corresponding to types in |
| 296 // |types_to_download| from |current_routes|. | 296 // |types_to_download| from |current_routes|. |
| 297 void BuildModelSafeParams( | 297 void BuildModelSafeParams(ModelTypeSet types_to_download, |
| 298 ModelTypeSet types_to_download, | 298 const ModelSafeRoutingInfo& current_routes, |
| 299 const ModelSafeRoutingInfo& current_routes, | 299 ModelSafeRoutingInfo* result_routes) { |
| 300 ModelSafeRoutingInfo* result_routes) { | |
| 301 for (ModelTypeSet::Iterator iter = types_to_download.First(); iter.Good(); | 300 for (ModelTypeSet::Iterator iter = types_to_download.First(); iter.Good(); |
| 302 iter.Inc()) { | 301 iter.Inc()) { |
| 303 ModelType type = iter.Get(); | 302 ModelType type = iter.Get(); |
| 304 ModelSafeRoutingInfo::const_iterator route = current_routes.find(type); | 303 ModelSafeRoutingInfo::const_iterator route = current_routes.find(type); |
| 305 DCHECK(route != current_routes.end()); | 304 DCHECK(route != current_routes.end()); |
| 306 ModelSafeGroup group = route->second; | 305 ModelSafeGroup group = route->second; |
| 307 (*result_routes)[type] = group; | 306 (*result_routes)[type] = group; |
| 308 } | 307 } |
| 309 } | 308 } |
| 310 | 309 |
| 311 } // namespace. | 310 } // namespace. |
| 312 | 311 |
| 313 void SyncSchedulerImpl::ScheduleConfiguration( | 312 void SyncSchedulerImpl::ScheduleConfiguration( |
| 314 const ConfigurationParams& params) { | 313 const ConfigurationParams& params) { |
| 315 DCHECK(CalledOnValidThread()); | 314 DCHECK(CalledOnValidThread()); |
| 316 DCHECK(IsConfigRelatedUpdateSourceValue(params.source)); | 315 DCHECK(IsConfigRelatedUpdateSourceValue(params.source)); |
| 317 DCHECK_EQ(CONFIGURATION_MODE, mode_); | 316 DCHECK_EQ(CONFIGURATION_MODE, mode_); |
| 318 DCHECK(!params.ready_task.is_null()); | 317 DCHECK(!params.ready_task.is_null()); |
| 319 CHECK(started_) << "Scheduler must be running to configure."; | 318 CHECK(started_) << "Scheduler must be running to configure."; |
| 320 SDVLOG(2) << "Reconfiguring syncer."; | 319 SDVLOG(2) << "Reconfiguring syncer."; |
| 321 | 320 |
| 322 // Only one configuration is allowed at a time. Verify we're not waiting | 321 // Only one configuration is allowed at a time. Verify we're not waiting |
| 323 // for a pending configure job. | 322 // for a pending configure job. |
| 324 DCHECK(!pending_configure_params_); | 323 DCHECK(!pending_configure_params_); |
| 325 | 324 |
| 326 ModelSafeRoutingInfo restricted_routes; | 325 ModelSafeRoutingInfo restricted_routes; |
| 327 BuildModelSafeParams(params.types_to_download, | 326 BuildModelSafeParams(params.types_to_download, params.routing_info, |
| 328 params.routing_info, | |
| 329 &restricted_routes); | 327 &restricted_routes); |
| 330 session_context_->SetRoutingInfo(restricted_routes); | 328 session_context_->SetRoutingInfo(restricted_routes); |
| 331 | 329 |
| 332 // Only reconfigure if we have types to download. | 330 // Only reconfigure if we have types to download. |
| 333 if (!params.types_to_download.Empty()) { | 331 if (!params.types_to_download.Empty()) { |
| 334 pending_configure_params_.reset(new ConfigurationParams(params)); | 332 pending_configure_params_.reset(new ConfigurationParams(params)); |
| 335 TrySyncSessionJob(); | 333 TrySyncSessionJob(); |
| 336 } else { | 334 } else { |
| 337 SDVLOG(2) << "No change in routing info, calling ready task directly."; | 335 SDVLOG(2) << "No change in routing info, calling ready task directly."; |
| 338 params.ready_task.Run(); | 336 params.ready_task.Run(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 | 388 |
| 391 return true; | 389 return true; |
| 392 } | 390 } |
| 393 | 391 |
| 394 void SyncSchedulerImpl::ScheduleLocalNudge( | 392 void SyncSchedulerImpl::ScheduleLocalNudge( |
| 395 ModelTypeSet types, | 393 ModelTypeSet types, |
| 396 const tracked_objects::Location& nudge_location) { | 394 const tracked_objects::Location& nudge_location) { |
| 397 DCHECK(CalledOnValidThread()); | 395 DCHECK(CalledOnValidThread()); |
| 398 DCHECK(!types.Empty()); | 396 DCHECK(!types.Empty()); |
| 399 | 397 |
| 400 SDVLOG_LOC(nudge_location, 2) | 398 SDVLOG_LOC(nudge_location, 2) << "Scheduling sync because of local change to " |
| 401 << "Scheduling sync because of local change to " | 399 << ModelTypeSetToString(types); |
| 402 << ModelTypeSetToString(types); | |
| 403 UpdateNudgeTimeRecords(types); | 400 UpdateNudgeTimeRecords(types); |
| 404 base::TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(types); | 401 base::TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(types); |
| 405 ScheduleNudgeImpl(nudge_delay, nudge_location); | 402 ScheduleNudgeImpl(nudge_delay, nudge_location); |
| 406 } | 403 } |
| 407 | 404 |
| 408 void SyncSchedulerImpl::ScheduleLocalRefreshRequest( | 405 void SyncSchedulerImpl::ScheduleLocalRefreshRequest( |
| 409 ModelTypeSet types, | 406 ModelTypeSet types, |
| 410 const tracked_objects::Location& nudge_location) { | 407 const tracked_objects::Location& nudge_location) { |
| 411 DCHECK(CalledOnValidThread()); | 408 DCHECK(CalledOnValidThread()); |
| 412 DCHECK(!types.Empty()); | 409 DCHECK(!types.Empty()); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 const tracked_objects::Location& nudge_location) { | 445 const tracked_objects::Location& nudge_location) { |
| 449 DCHECK(CalledOnValidThread()); | 446 DCHECK(CalledOnValidThread()); |
| 450 CHECK(!syncer_->IsSyncing()); | 447 CHECK(!syncer_->IsSyncing()); |
| 451 | 448 |
| 452 if (!started_) { | 449 if (!started_) { |
| 453 SDVLOG_LOC(nudge_location, 2) | 450 SDVLOG_LOC(nudge_location, 2) |
| 454 << "Dropping nudge, scheduler is not running."; | 451 << "Dropping nudge, scheduler is not running."; |
| 455 return; | 452 return; |
| 456 } | 453 } |
| 457 | 454 |
| 458 SDVLOG_LOC(nudge_location, 2) | 455 SDVLOG_LOC(nudge_location, 2) << "In ScheduleNudgeImpl with delay " |
| 459 << "In ScheduleNudgeImpl with delay " | 456 << delay.InMilliseconds() << " ms"; |
| 460 << delay.InMilliseconds() << " ms"; | |
| 461 | 457 |
| 462 if (!CanRunNudgeJobNow(NORMAL_PRIORITY)) | 458 if (!CanRunNudgeJobNow(NORMAL_PRIORITY)) |
| 463 return; | 459 return; |
| 464 | 460 |
| 465 TimeTicks incoming_run_time = TimeTicks::Now() + delay; | 461 TimeTicks incoming_run_time = TimeTicks::Now() + delay; |
| 466 if (!scheduled_nudge_time_.is_null() && | 462 if (!scheduled_nudge_time_.is_null() && |
| 467 (scheduled_nudge_time_ < incoming_run_time)) { | 463 (scheduled_nudge_time_ < incoming_run_time)) { |
| 468 // Old job arrives sooner than this one. Don't reschedule it. | 464 // Old job arrives sooner than this one. Don't reschedule it. |
| 469 return; | 465 return; |
| 470 } | 466 } |
| 471 | 467 |
| 472 // Either there is no existing nudge in flight or the incoming nudge should be | 468 // Either there is no existing nudge in flight or the incoming nudge should be |
| 473 // made to arrive first (preempt) the existing nudge. We reschedule in either | 469 // made to arrive first (preempt) the existing nudge. We reschedule in either |
| 474 // case. | 470 // case. |
| 475 SDVLOG_LOC(nudge_location, 2) | 471 SDVLOG_LOC(nudge_location, 2) << "Scheduling a nudge with " |
| 476 << "Scheduling a nudge with " | 472 << delay.InMilliseconds() << " ms delay"; |
| 477 << delay.InMilliseconds() << " ms delay"; | |
| 478 scheduled_nudge_time_ = incoming_run_time; | 473 scheduled_nudge_time_ = incoming_run_time; |
| 479 pending_wakeup_timer_.Start( | 474 pending_wakeup_timer_.Start( |
| 480 nudge_location, | 475 nudge_location, delay, base::Bind(&SyncSchedulerImpl::PerformDelayedNudge, |
| 481 delay, | 476 weak_ptr_factory_.GetWeakPtr())); |
| 482 base::Bind(&SyncSchedulerImpl::PerformDelayedNudge, | |
| 483 weak_ptr_factory_.GetWeakPtr())); | |
| 484 } | 477 } |
| 485 | 478 |
| 486 const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) { | 479 const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) { |
| 487 switch (mode) { | 480 switch (mode) { |
| 488 ENUM_CASE(CONFIGURATION_MODE); | 481 ENUM_CASE(CONFIGURATION_MODE); |
| 489 ENUM_CASE(CLEAR_SERVER_DATA_MODE); | 482 ENUM_CASE(CLEAR_SERVER_DATA_MODE); |
| 490 ENUM_CASE(NORMAL_MODE); | 483 ENUM_CASE(NORMAL_MODE); |
| 491 } | 484 } |
| 492 return ""; | 485 return ""; |
| 493 } | 486 } |
| 494 | 487 |
| 495 void SyncSchedulerImpl::SetDefaultNudgeDelay(base::TimeDelta delay_ms) { | 488 void SyncSchedulerImpl::SetDefaultNudgeDelay(base::TimeDelta delay_ms) { |
| 496 DCHECK(CalledOnValidThread()); | 489 DCHECK(CalledOnValidThread()); |
| 497 nudge_tracker_.SetDefaultNudgeDelay(delay_ms); | 490 nudge_tracker_.SetDefaultNudgeDelay(delay_ms); |
| 498 } | 491 } |
| 499 | 492 |
| 500 void SyncSchedulerImpl::DoNudgeSyncSessionJob(JobPriority priority) { | 493 void SyncSchedulerImpl::DoNudgeSyncSessionJob(JobPriority priority) { |
| 501 DCHECK(CalledOnValidThread()); | 494 DCHECK(CalledOnValidThread()); |
| 502 DCHECK(CanRunNudgeJobNow(priority)); | 495 DCHECK(CanRunNudgeJobNow(priority)); |
| 503 | 496 |
| 504 DVLOG(2) << "Will run normal mode sync cycle with types " | 497 DVLOG(2) << "Will run normal mode sync cycle with types " |
| 505 << ModelTypeSetToString(session_context_->GetEnabledTypes()); | 498 << ModelTypeSetToString(session_context_->GetEnabledTypes()); |
| 506 std::unique_ptr<SyncSession> session( | 499 std::unique_ptr<SyncSession> session( |
| 507 SyncSession::Build(session_context_, this)); | 500 SyncSession::Build(session_context_, this)); |
| 508 bool success = syncer_->NormalSyncShare( | 501 bool success = syncer_->NormalSyncShare(GetEnabledAndUnthrottledTypes(), |
| 509 GetEnabledAndUnthrottledTypes(), &nudge_tracker_, session.get()); | 502 &nudge_tracker_, session.get()); |
| 510 | 503 |
| 511 if (success) { | 504 if (success) { |
| 512 // That cycle took care of any outstanding work we had. | 505 // That cycle took care of any outstanding work we had. |
| 513 SDVLOG(2) << "Nudge succeeded."; | 506 SDVLOG(2) << "Nudge succeeded."; |
| 514 nudge_tracker_.RecordSuccessfulSyncCycle(); | 507 nudge_tracker_.RecordSuccessfulSyncCycle(); |
| 515 scheduled_nudge_time_ = base::TimeTicks(); | 508 scheduled_nudge_time_ = base::TimeTicks(); |
| 516 HandleSuccess(); | 509 HandleSuccess(); |
| 517 | 510 |
| 518 // If this was a canary, we may need to restart the poll timer (the poll | 511 // If this was a canary, we may need to restart the poll timer (the poll |
| 519 // timer may have fired while the scheduler was in an error state, ignoring | 512 // timer may have fired while the scheduler was in an error state, ignoring |
| (...skipping 17 matching lines...) Expand all Loading... |
| 537 RunAndReset(&pending_configure_params_->retry_task); | 530 RunAndReset(&pending_configure_params_->retry_task); |
| 538 return; | 531 return; |
| 539 } | 532 } |
| 540 | 533 |
| 541 SDVLOG(2) << "Will run configure SyncShare with types " | 534 SDVLOG(2) << "Will run configure SyncShare with types " |
| 542 << ModelTypeSetToString(session_context_->GetEnabledTypes()); | 535 << ModelTypeSetToString(session_context_->GetEnabledTypes()); |
| 543 std::unique_ptr<SyncSession> session( | 536 std::unique_ptr<SyncSession> session( |
| 544 SyncSession::Build(session_context_, this)); | 537 SyncSession::Build(session_context_, this)); |
| 545 bool success = syncer_->ConfigureSyncShare( | 538 bool success = syncer_->ConfigureSyncShare( |
| 546 pending_configure_params_->types_to_download, | 539 pending_configure_params_->types_to_download, |
| 547 pending_configure_params_->source, | 540 pending_configure_params_->source, session.get()); |
| 548 session.get()); | |
| 549 | 541 |
| 550 if (success) { | 542 if (success) { |
| 551 SDVLOG(2) << "Configure succeeded."; | 543 SDVLOG(2) << "Configure succeeded."; |
| 552 pending_configure_params_->ready_task.Run(); | 544 pending_configure_params_->ready_task.Run(); |
| 553 pending_configure_params_.reset(); | 545 pending_configure_params_.reset(); |
| 554 HandleSuccess(); | 546 HandleSuccess(); |
| 555 } else { | 547 } else { |
| 556 HandleFailure(session->status_controller().model_neutral_state()); | 548 HandleFailure(session->status_controller().model_neutral_state()); |
| 557 // Sync cycle might receive response from server that causes scheduler to | 549 // Sync cycle might receive response from server that causes scheduler to |
| 558 // stop and draws pending_configure_params_ invalid. | 550 // stop and draws pending_configure_params_ invalid. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 const sessions::ModelNeutralState& model_neutral_state) { | 587 const sessions::ModelNeutralState& model_neutral_state) { |
| 596 if (IsCurrentlyThrottled()) { | 588 if (IsCurrentlyThrottled()) { |
| 597 SDVLOG(2) << "Was throttled during previous sync cycle."; | 589 SDVLOG(2) << "Was throttled during previous sync cycle."; |
| 598 } else if (!IsBackingOff()) { | 590 } else if (!IsBackingOff()) { |
| 599 // Setup our backoff if this is our first such failure. | 591 // Setup our backoff if this is our first such failure. |
| 600 TimeDelta length = delay_provider_->GetDelay( | 592 TimeDelta length = delay_provider_->GetDelay( |
| 601 delay_provider_->GetInitialDelay(model_neutral_state)); | 593 delay_provider_->GetInitialDelay(model_neutral_state)); |
| 602 wait_interval_.reset( | 594 wait_interval_.reset( |
| 603 new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, length)); | 595 new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, length)); |
| 604 SDVLOG(2) << "Sync cycle failed. Will back off for " | 596 SDVLOG(2) << "Sync cycle failed. Will back off for " |
| 605 << wait_interval_->length.InMilliseconds() << "ms."; | 597 << wait_interval_->length.InMilliseconds() << "ms."; |
| 606 } else { | 598 } else { |
| 607 // Increase our backoff interval and schedule another retry. | 599 // Increase our backoff interval and schedule another retry. |
| 608 TimeDelta length = delay_provider_->GetDelay(wait_interval_->length); | 600 TimeDelta length = delay_provider_->GetDelay(wait_interval_->length); |
| 609 wait_interval_.reset( | 601 wait_interval_.reset( |
| 610 new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, length)); | 602 new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, length)); |
| 611 SDVLOG(2) << "Sync cycle failed. Will back off for " | 603 SDVLOG(2) << "Sync cycle failed. Will back off for " |
| 612 << wait_interval_->length.InMilliseconds() << "ms."; | 604 << wait_interval_->length.InMilliseconds() << "ms."; |
| 613 } | 605 } |
| 614 RestartWaiting(); | 606 RestartWaiting(); |
| 615 } | 607 } |
| 616 | 608 |
| 617 void SyncSchedulerImpl::DoPollSyncSessionJob() { | 609 void SyncSchedulerImpl::DoPollSyncSessionJob() { |
| 618 SDVLOG(2) << "Polling with types " | 610 SDVLOG(2) << "Polling with types " |
| 619 << ModelTypeSetToString(GetEnabledAndUnthrottledTypes()); | 611 << ModelTypeSetToString(GetEnabledAndUnthrottledTypes()); |
| 620 std::unique_ptr<SyncSession> session( | 612 std::unique_ptr<SyncSession> session( |
| 621 SyncSession::Build(session_context_, this)); | 613 SyncSession::Build(session_context_, this)); |
| 622 bool success = syncer_->PollSyncShare( | 614 bool success = |
| 623 GetEnabledAndUnthrottledTypes(), | 615 syncer_->PollSyncShare(GetEnabledAndUnthrottledTypes(), session.get()); |
| 624 session.get()); | |
| 625 | 616 |
| 626 // Only restart the timer if the poll succeeded. Otherwise rely on normal | 617 // Only restart the timer if the poll succeeded. Otherwise rely on normal |
| 627 // failure handling to retry with backoff. | 618 // failure handling to retry with backoff. |
| 628 if (success) { | 619 if (success) { |
| 629 AdjustPolling(FORCE_RESET); | 620 AdjustPolling(FORCE_RESET); |
| 630 HandleSuccess(); | 621 HandleSuccess(); |
| 631 } else { | 622 } else { |
| 632 HandleFailure(session->status_controller().model_neutral_state()); | 623 HandleFailure(session->status_controller().model_neutral_state()); |
| 633 } | 624 } |
| 634 } | 625 } |
| 635 | 626 |
| 636 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { | 627 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) { |
| 637 DCHECK(CalledOnValidThread()); | 628 DCHECK(CalledOnValidThread()); |
| 638 base::TimeTicks now = TimeTicks::Now(); | 629 base::TimeTicks now = TimeTicks::Now(); |
| 639 // Update timing information for how often datatypes are triggering nudges. | 630 // Update timing information for how often datatypes are triggering nudges. |
| 640 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { | 631 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { |
| 641 base::TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()]; | 632 base::TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()]; |
| 642 last_local_nudges_by_model_type_[iter.Get()] = now; | 633 last_local_nudges_by_model_type_[iter.Get()] = now; |
| 643 if (previous.is_null()) | 634 if (previous.is_null()) |
| 644 continue; | 635 continue; |
| 645 | 636 |
| 646 #define PER_DATA_TYPE_MACRO(type_str) \ | 637 #define PER_DATA_TYPE_MACRO(type_str) \ |
| 647 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); | 638 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); |
| 648 SYNC_DATA_TYPE_HISTOGRAM(iter.Get()); | 639 SYNC_DATA_TYPE_HISTOGRAM(iter.Get()); |
| 649 #undef PER_DATA_TYPE_MACRO | 640 #undef PER_DATA_TYPE_MACRO |
| 650 } | 641 } |
| 651 } | 642 } |
| 652 | 643 |
| 653 TimeDelta SyncSchedulerImpl::GetPollInterval() { | 644 TimeDelta SyncSchedulerImpl::GetPollInterval() { |
| 654 return (!session_context_->notifications_enabled() || | 645 return (!session_context_->notifications_enabled() || |
| 655 !session_context_->ShouldFetchUpdatesBeforeCommit()) ? | 646 !session_context_->ShouldFetchUpdatesBeforeCommit()) |
| 656 syncer_short_poll_interval_seconds_ : | 647 ? syncer_short_poll_interval_seconds_ |
| 657 syncer_long_poll_interval_seconds_; | 648 : syncer_long_poll_interval_seconds_; |
| 658 } | 649 } |
| 659 | 650 |
| 660 void SyncSchedulerImpl::AdjustPolling(PollAdjustType type) { | 651 void SyncSchedulerImpl::AdjustPolling(PollAdjustType type) { |
| 661 DCHECK(CalledOnValidThread()); | 652 DCHECK(CalledOnValidThread()); |
| 662 if (!started_) | 653 if (!started_) |
| 663 return; | 654 return; |
| 664 | 655 |
| 665 TimeDelta poll_interval = GetPollInterval(); | 656 TimeDelta poll_interval = GetPollInterval(); |
| 666 TimeDelta poll_delay = poll_interval; | 657 TimeDelta poll_delay = poll_interval; |
| 667 const TimeTicks now = TimeTicks::Now(); | 658 const TimeTicks now = TimeTicks::Now(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 698 // Adjust poll rate. Start will reset the timer if it was already running. | 689 // Adjust poll rate. Start will reset the timer if it was already running. |
| 699 poll_timer_.Start(FROM_HERE, poll_delay, this, | 690 poll_timer_.Start(FROM_HERE, poll_delay, this, |
| 700 &SyncSchedulerImpl::PollTimerCallback); | 691 &SyncSchedulerImpl::PollTimerCallback); |
| 701 } | 692 } |
| 702 | 693 |
| 703 void SyncSchedulerImpl::RestartWaiting() { | 694 void SyncSchedulerImpl::RestartWaiting() { |
| 704 CHECK(wait_interval_.get()); | 695 CHECK(wait_interval_.get()); |
| 705 DCHECK(wait_interval_->length >= TimeDelta::FromSeconds(0)); | 696 DCHECK(wait_interval_->length >= TimeDelta::FromSeconds(0)); |
| 706 NotifyRetryTime(base::Time::Now() + wait_interval_->length); | 697 NotifyRetryTime(base::Time::Now() + wait_interval_->length); |
| 707 SDVLOG(2) << "Starting WaitInterval timer of length " | 698 SDVLOG(2) << "Starting WaitInterval timer of length " |
| 708 << wait_interval_->length.InMilliseconds() << "ms."; | 699 << wait_interval_->length.InMilliseconds() << "ms."; |
| 709 if (wait_interval_->mode == WaitInterval::THROTTLED) { | 700 if (wait_interval_->mode == WaitInterval::THROTTLED) { |
| 710 pending_wakeup_timer_.Start( | 701 pending_wakeup_timer_.Start(FROM_HERE, wait_interval_->length, |
| 711 FROM_HERE, | 702 base::Bind(&SyncSchedulerImpl::Unthrottle, |
| 712 wait_interval_->length, | 703 weak_ptr_factory_.GetWeakPtr())); |
| 713 base::Bind(&SyncSchedulerImpl::Unthrottle, | |
| 714 weak_ptr_factory_.GetWeakPtr())); | |
| 715 } else { | 704 } else { |
| 716 pending_wakeup_timer_.Start( | 705 pending_wakeup_timer_.Start( |
| 717 FROM_HERE, | 706 FROM_HERE, wait_interval_->length, |
| 718 wait_interval_->length, | |
| 719 base::Bind(&SyncSchedulerImpl::ExponentialBackoffRetry, | 707 base::Bind(&SyncSchedulerImpl::ExponentialBackoffRetry, |
| 720 weak_ptr_factory_.GetWeakPtr())); | 708 weak_ptr_factory_.GetWeakPtr())); |
| 721 } | 709 } |
| 722 } | 710 } |
| 723 | 711 |
| 724 void SyncSchedulerImpl::Stop() { | 712 void SyncSchedulerImpl::Stop() { |
| 725 DCHECK(CalledOnValidThread()); | 713 DCHECK(CalledOnValidThread()); |
| 726 SDVLOG(2) << "Stop called"; | 714 SDVLOG(2) << "Stop called"; |
| 727 | 715 |
| 728 // Kill any in-flight method calls. | 716 // Kill any in-flight method calls. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 } | 774 } |
| 787 | 775 |
| 788 if (IsBackingOff() && !pending_wakeup_timer_.IsRunning()) { | 776 if (IsBackingOff() && !pending_wakeup_timer_.IsRunning()) { |
| 789 // If we succeeded, our wait interval would have been cleared. If it hasn't | 777 // If we succeeded, our wait interval would have been cleared. If it hasn't |
| 790 // been cleared, then we should increase our backoff interval and schedule | 778 // been cleared, then we should increase our backoff interval and schedule |
| 791 // another retry. | 779 // another retry. |
| 792 TimeDelta length = delay_provider_->GetDelay(wait_interval_->length); | 780 TimeDelta length = delay_provider_->GetDelay(wait_interval_->length); |
| 793 wait_interval_.reset( | 781 wait_interval_.reset( |
| 794 new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, length)); | 782 new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, length)); |
| 795 SDVLOG(2) << "Sync cycle failed. Will back off for " | 783 SDVLOG(2) << "Sync cycle failed. Will back off for " |
| 796 << wait_interval_->length.InMilliseconds() << "ms."; | 784 << wait_interval_->length.InMilliseconds() << "ms."; |
| 797 RestartWaiting(); | 785 RestartWaiting(); |
| 798 } | 786 } |
| 799 } | 787 } |
| 800 | 788 |
| 801 void SyncSchedulerImpl::PollTimerCallback() { | 789 void SyncSchedulerImpl::PollTimerCallback() { |
| 802 DCHECK(CalledOnValidThread()); | 790 DCHECK(CalledOnValidThread()); |
| 803 CHECK(!syncer_->IsSyncing()); | 791 CHECK(!syncer_->IsSyncing()); |
| 804 | 792 |
| 805 TrySyncSessionJob(); | 793 TrySyncSessionJob(); |
| 806 } | 794 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 828 | 816 |
| 829 void SyncSchedulerImpl::TypeUnthrottle(base::TimeTicks unthrottle_time) { | 817 void SyncSchedulerImpl::TypeUnthrottle(base::TimeTicks unthrottle_time) { |
| 830 DCHECK(CalledOnValidThread()); | 818 DCHECK(CalledOnValidThread()); |
| 831 nudge_tracker_.UpdateTypeThrottlingState(unthrottle_time); | 819 nudge_tracker_.UpdateTypeThrottlingState(unthrottle_time); |
| 832 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); | 820 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); |
| 833 | 821 |
| 834 if (nudge_tracker_.IsAnyTypeThrottled()) { | 822 if (nudge_tracker_.IsAnyTypeThrottled()) { |
| 835 const base::TimeTicks now = base::TimeTicks::Now(); | 823 const base::TimeTicks now = base::TimeTicks::Now(); |
| 836 base::TimeDelta time_until_next_unthrottle = | 824 base::TimeDelta time_until_next_unthrottle = |
| 837 nudge_tracker_.GetTimeUntilNextUnthrottle(now); | 825 nudge_tracker_.GetTimeUntilNextUnthrottle(now); |
| 838 type_unthrottle_timer_.Start( | 826 type_unthrottle_timer_.Start(FROM_HERE, time_until_next_unthrottle, |
| 839 FROM_HERE, | 827 base::Bind(&SyncSchedulerImpl::TypeUnthrottle, |
| 840 time_until_next_unthrottle, | 828 weak_ptr_factory_.GetWeakPtr(), |
| 841 base::Bind(&SyncSchedulerImpl::TypeUnthrottle, | 829 now + time_until_next_unthrottle)); |
| 842 weak_ptr_factory_.GetWeakPtr(), | |
| 843 now + time_until_next_unthrottle)); | |
| 844 } | 830 } |
| 845 | 831 |
| 846 // Maybe this is a good time to run a nudge job. Let's try it. | 832 // Maybe this is a good time to run a nudge job. Let's try it. |
| 847 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) | 833 if (nudge_tracker_.IsSyncRequired() && CanRunNudgeJobNow(NORMAL_PRIORITY)) |
| 848 TrySyncSessionJob(); | 834 TrySyncSessionJob(); |
| 849 } | 835 } |
| 850 | 836 |
| 851 void SyncSchedulerImpl::PerformDelayedNudge() { | 837 void SyncSchedulerImpl::PerformDelayedNudge() { |
| 852 // Circumstances may have changed since we scheduled this delayed nudge. | 838 // Circumstances may have changed since we scheduled this delayed nudge. |
| 853 // We must check to see if it's OK to run the job before we do so. | 839 // We must check to see if it's OK to run the job before we do so. |
| 854 if (CanRunNudgeJobNow(NORMAL_PRIORITY)) | 840 if (CanRunNudgeJobNow(NORMAL_PRIORITY)) |
| 855 TrySyncSessionJob(); | 841 TrySyncSessionJob(); |
| 856 | 842 |
| 857 // We're not responsible for setting up any retries here. The functions that | 843 // We're not responsible for setting up any retries here. The functions that |
| 858 // first put us into a state that prevents successful sync cycles (eg. global | 844 // first put us into a state that prevents successful sync cycles (eg. global |
| 859 // throttling, type throttling, network errors, transient errors) will also | 845 // throttling, type throttling, network errors, transient errors) will also |
| 860 // setup the appropriate retry logic (eg. retry after timeout, exponential | 846 // setup the appropriate retry logic (eg. retry after timeout, exponential |
| 861 // backoff, retry when the network changes). | 847 // backoff, retry when the network changes). |
| 862 } | 848 } |
| 863 | 849 |
| 864 void SyncSchedulerImpl::ExponentialBackoffRetry() { | 850 void SyncSchedulerImpl::ExponentialBackoffRetry() { |
| 865 TryCanaryJob(); | 851 TryCanaryJob(); |
| 866 } | 852 } |
| 867 | 853 |
| 868 void SyncSchedulerImpl::NotifyRetryTime(base::Time retry_time) { | 854 void SyncSchedulerImpl::NotifyRetryTime(base::Time retry_time) { |
| 869 FOR_EACH_OBSERVER(SyncEngineEventListener, | 855 FOR_EACH_OBSERVER(SyncEngineEventListener, *session_context_->listeners(), |
| 870 *session_context_->listeners(), | |
| 871 OnRetryTimeChanged(retry_time)); | 856 OnRetryTimeChanged(retry_time)); |
| 872 } | 857 } |
| 873 | 858 |
| 874 void SyncSchedulerImpl::NotifyThrottledTypesChanged(ModelTypeSet types) { | 859 void SyncSchedulerImpl::NotifyThrottledTypesChanged(ModelTypeSet types) { |
| 875 FOR_EACH_OBSERVER(SyncEngineEventListener, | 860 FOR_EACH_OBSERVER(SyncEngineEventListener, *session_context_->listeners(), |
| 876 *session_context_->listeners(), | |
| 877 OnThrottledTypesChanged(types)); | 861 OnThrottledTypesChanged(types)); |
| 878 } | 862 } |
| 879 | 863 |
| 880 bool SyncSchedulerImpl::IsBackingOff() const { | 864 bool SyncSchedulerImpl::IsBackingOff() const { |
| 881 DCHECK(CalledOnValidThread()); | 865 DCHECK(CalledOnValidThread()); |
| 882 return wait_interval_.get() && wait_interval_->mode == | 866 return wait_interval_.get() && |
| 883 WaitInterval::EXPONENTIAL_BACKOFF; | 867 wait_interval_->mode == WaitInterval::EXPONENTIAL_BACKOFF; |
| 884 } | 868 } |
| 885 | 869 |
| 886 void SyncSchedulerImpl::OnThrottled(const base::TimeDelta& throttle_duration) { | 870 void SyncSchedulerImpl::OnThrottled(const base::TimeDelta& throttle_duration) { |
| 887 DCHECK(CalledOnValidThread()); | 871 DCHECK(CalledOnValidThread()); |
| 888 wait_interval_.reset(new WaitInterval(WaitInterval::THROTTLED, | 872 wait_interval_.reset( |
| 889 throttle_duration)); | 873 new WaitInterval(WaitInterval::THROTTLED, throttle_duration)); |
| 890 NotifyRetryTime(base::Time::Now() + wait_interval_->length); | 874 NotifyRetryTime(base::Time::Now() + wait_interval_->length); |
| 891 NotifyThrottledTypesChanged(ModelTypeSet::All()); | 875 NotifyThrottledTypesChanged(ModelTypeSet::All()); |
| 892 } | 876 } |
| 893 | 877 |
| 894 void SyncSchedulerImpl::OnTypesThrottled( | 878 void SyncSchedulerImpl::OnTypesThrottled( |
| 895 ModelTypeSet types, | 879 ModelTypeSet types, |
| 896 const base::TimeDelta& throttle_duration) { | 880 const base::TimeDelta& throttle_duration) { |
| 897 base::TimeTicks now = base::TimeTicks::Now(); | 881 base::TimeTicks now = base::TimeTicks::Now(); |
| 898 | 882 |
| 899 SDVLOG(1) << "Throttling " << ModelTypeSetToString(types) << " for " | 883 SDVLOG(1) << "Throttling " << ModelTypeSetToString(types) << " for " |
| 900 << throttle_duration.InMinutes() << " minutes."; | 884 << throttle_duration.InMinutes() << " minutes."; |
| 901 | 885 |
| 902 nudge_tracker_.SetTypesThrottledUntil(types, throttle_duration, now); | 886 nudge_tracker_.SetTypesThrottledUntil(types, throttle_duration, now); |
| 903 base::TimeDelta time_until_next_unthrottle = | 887 base::TimeDelta time_until_next_unthrottle = |
| 904 nudge_tracker_.GetTimeUntilNextUnthrottle(now); | 888 nudge_tracker_.GetTimeUntilNextUnthrottle(now); |
| 905 type_unthrottle_timer_.Start( | 889 type_unthrottle_timer_.Start(FROM_HERE, time_until_next_unthrottle, |
| 906 FROM_HERE, | 890 base::Bind(&SyncSchedulerImpl::TypeUnthrottle, |
| 907 time_until_next_unthrottle, | 891 weak_ptr_factory_.GetWeakPtr(), |
| 908 base::Bind(&SyncSchedulerImpl::TypeUnthrottle, | 892 now + time_until_next_unthrottle)); |
| 909 weak_ptr_factory_.GetWeakPtr(), | |
| 910 now + time_until_next_unthrottle)); | |
| 911 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); | 893 NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); |
| 912 } | 894 } |
| 913 | 895 |
| 914 bool SyncSchedulerImpl::IsCurrentlyThrottled() { | 896 bool SyncSchedulerImpl::IsCurrentlyThrottled() { |
| 915 DCHECK(CalledOnValidThread()); | 897 DCHECK(CalledOnValidThread()); |
| 916 return wait_interval_.get() && wait_interval_->mode == | 898 return wait_interval_.get() && |
| 917 WaitInterval::THROTTLED; | 899 wait_interval_->mode == WaitInterval::THROTTLED; |
| 918 } | 900 } |
| 919 | 901 |
| 920 void SyncSchedulerImpl::OnReceivedShortPollIntervalUpdate( | 902 void SyncSchedulerImpl::OnReceivedShortPollIntervalUpdate( |
| 921 const base::TimeDelta& new_interval) { | 903 const base::TimeDelta& new_interval) { |
| 922 DCHECK(CalledOnValidThread()); | 904 DCHECK(CalledOnValidThread()); |
| 923 if (new_interval == syncer_short_poll_interval_seconds_) | 905 if (new_interval == syncer_short_poll_interval_seconds_) |
| 924 return; | 906 return; |
| 925 SDVLOG(1) << "Updating short poll interval to " << new_interval.InMinutes() | 907 SDVLOG(1) << "Updating short poll interval to " << new_interval.InMinutes() |
| 926 << " minutes."; | 908 << " minutes."; |
| 927 syncer_short_poll_interval_seconds_ = new_interval; | 909 syncer_short_poll_interval_seconds_ = new_interval; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 954 | 936 |
| 955 void SyncSchedulerImpl::OnSyncProtocolError( | 937 void SyncSchedulerImpl::OnSyncProtocolError( |
| 956 const SyncProtocolError& sync_protocol_error) { | 938 const SyncProtocolError& sync_protocol_error) { |
| 957 DCHECK(CalledOnValidThread()); | 939 DCHECK(CalledOnValidThread()); |
| 958 if (ShouldRequestEarlyExit(sync_protocol_error)) { | 940 if (ShouldRequestEarlyExit(sync_protocol_error)) { |
| 959 SDVLOG(2) << "Sync Scheduler requesting early exit."; | 941 SDVLOG(2) << "Sync Scheduler requesting early exit."; |
| 960 Stop(); | 942 Stop(); |
| 961 } | 943 } |
| 962 if (IsActionableError(sync_protocol_error)) { | 944 if (IsActionableError(sync_protocol_error)) { |
| 963 SDVLOG(2) << "OnActionableError"; | 945 SDVLOG(2) << "OnActionableError"; |
| 964 FOR_EACH_OBSERVER(SyncEngineEventListener, | 946 FOR_EACH_OBSERVER(SyncEngineEventListener, *session_context_->listeners(), |
| 965 *session_context_->listeners(), | |
| 966 OnActionableError(sync_protocol_error)); | 947 OnActionableError(sync_protocol_error)); |
| 967 } | 948 } |
| 968 } | 949 } |
| 969 | 950 |
| 970 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const base::TimeDelta& delay) { | 951 void SyncSchedulerImpl::OnReceivedGuRetryDelay(const base::TimeDelta& delay) { |
| 971 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + delay); | 952 nudge_tracker_.SetNextRetryTime(TimeTicks::Now() + delay); |
| 972 retry_timer_.Start(FROM_HERE, delay, this, | 953 retry_timer_.Start(FROM_HERE, delay, this, |
| 973 &SyncSchedulerImpl::RetryTimerCallback); | 954 &SyncSchedulerImpl::RetryTimerCallback); |
| 974 } | 955 } |
| 975 | 956 |
| 976 void SyncSchedulerImpl::OnReceivedMigrationRequest(ModelTypeSet types) { | 957 void SyncSchedulerImpl::OnReceivedMigrationRequest(ModelTypeSet types) { |
| 977 FOR_EACH_OBSERVER(SyncEngineEventListener, | 958 FOR_EACH_OBSERVER(SyncEngineEventListener, *session_context_->listeners(), |
| 978 *session_context_->listeners(), | 959 OnMigrationRequested(types)); |
| 979 OnMigrationRequested(types)); | |
| 980 } | 960 } |
| 981 | 961 |
| 982 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { | 962 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { |
| 983 DCHECK(CalledOnValidThread()); | 963 DCHECK(CalledOnValidThread()); |
| 984 session_context_->set_notifications_enabled(notifications_enabled); | 964 session_context_->set_notifications_enabled(notifications_enabled); |
| 985 if (notifications_enabled) | 965 if (notifications_enabled) |
| 986 nudge_tracker_.OnInvalidationsEnabled(); | 966 nudge_tracker_.OnInvalidationsEnabled(); |
| 987 else | 967 else |
| 988 nudge_tracker_.OnInvalidationsDisabled(); | 968 nudge_tracker_.OnInvalidationsDisabled(); |
| 989 } | 969 } |
| 990 | 970 |
| 991 #undef SDVLOG_LOC | 971 #undef SDVLOG_LOC |
| 992 | 972 |
| 993 #undef SDVLOG | 973 #undef SDVLOG |
| 994 | 974 |
| 995 #undef SLOG | 975 #undef SLOG |
| 996 | 976 |
| 997 #undef ENUM_CASE | 977 #undef ENUM_CASE |
| 998 | 978 |
| 999 } // namespace syncer | 979 } // namespace syncer |
| OLD | NEW |