| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/sync/engine/sync_scheduler.h" | 5 #include "chrome/browser/sync/engine/sync_scheduler.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 | 9 |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 return ""; | 51 return ""; |
| 52 } | 52 } |
| 53 | 53 |
| 54 SyncScheduler::SyncSessionJob::SyncSessionJob() | 54 SyncScheduler::SyncSessionJob::SyncSessionJob() |
| 55 : purpose(UNKNOWN), | 55 : purpose(UNKNOWN), |
| 56 is_canary_job(false) { | 56 is_canary_job(false) { |
| 57 } | 57 } |
| 58 | 58 |
| 59 SyncScheduler::SyncSessionJob::~SyncSessionJob() {} | 59 SyncScheduler::SyncSessionJob::~SyncSessionJob() {} |
| 60 | 60 |
| 61 SyncScheduler::SyncSessionJob::SyncSessionJob(SyncSessionJobPurpose purpose, | 61 SyncScheduler::SyncSessionJob::SyncSessionJob( |
| 62 SyncSessionJobPurpose purpose, |
| 62 base::TimeTicks start, | 63 base::TimeTicks start, |
| 63 linked_ptr<sessions::SyncSession> session, bool is_canary_job, | 64 linked_ptr<sessions::SyncSession> session, bool is_canary_job, |
| 64 const tracked_objects::Location& from_here) : purpose(purpose), | 65 const base::Closure& on_success, |
| 65 scheduled_start(start), | 66 const tracked_objects::Location& from_here) |
| 66 session(session), | 67 : purpose(purpose), |
| 67 is_canary_job(is_canary_job), | 68 scheduled_start(start), |
| 68 from_here(from_here) { | 69 session(session), |
| 70 is_canary_job(is_canary_job), |
| 71 on_success(on_success), |
| 72 from_here(from_here) { |
| 69 } | 73 } |
| 70 | 74 |
| 71 const char* SyncScheduler::SyncSessionJob::GetPurposeString( | 75 const char* SyncScheduler::SyncSessionJob::GetPurposeString( |
| 72 SyncScheduler::SyncSessionJob::SyncSessionJobPurpose purpose) { | 76 SyncScheduler::SyncSessionJob::SyncSessionJobPurpose purpose) { |
| 73 switch (purpose) { | 77 switch (purpose) { |
| 74 ENUM_CASE(UNKNOWN); | 78 ENUM_CASE(UNKNOWN); |
| 75 ENUM_CASE(POLL); | 79 ENUM_CASE(POLL); |
| 76 ENUM_CASE(NUDGE); | 80 ENUM_CASE(NUDGE); |
| 77 ENUM_CASE(CLEAR_USER_DATA); | 81 ENUM_CASE(CLEAR_USER_DATA); |
| 78 ENUM_CASE(CONFIGURATION); | 82 ENUM_CASE(CONFIGURATION); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 DoCanaryJob(); | 196 DoCanaryJob(); |
| 193 } | 197 } |
| 194 | 198 |
| 195 if (old_server_connection_ok != server_connection_ok_) { | 199 if (old_server_connection_ok != server_connection_ok_) { |
| 196 const char* transition = | 200 const char* transition = |
| 197 server_connection_ok_ ? "down -> up" : "up -> down"; | 201 server_connection_ok_ ? "down -> up" : "up -> down"; |
| 198 SVLOG(2) << "Server connection changed: " << transition; | 202 SVLOG(2) << "Server connection changed: " << transition; |
| 199 } | 203 } |
| 200 } | 204 } |
| 201 | 205 |
| 202 void SyncScheduler::Start(Mode mode, ModeChangeCallback* callback) { | 206 void SyncScheduler::Start(Mode mode, const base::Closure& callback) { |
| 203 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 207 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 204 std::string thread_name = MessageLoop::current()->thread_name(); | 208 std::string thread_name = MessageLoop::current()->thread_name(); |
| 205 if (thread_name.empty()) | 209 if (thread_name.empty()) |
| 206 thread_name = "<Main thread>"; | 210 thread_name = "<Main thread>"; |
| 207 SVLOG(2) << "Start called from thread " | 211 SVLOG(2) << "Start called from thread " |
| 208 << thread_name << " with mode " << GetModeString(mode); | 212 << thread_name << " with mode " << GetModeString(mode); |
| 209 if (!started_) { | 213 if (!started_) { |
| 210 WatchConnectionManager(); | 214 WatchConnectionManager(); |
| 211 PostTask(FROM_HERE, "SendInitialSnapshot", | 215 PostTask(FROM_HERE, "SendInitialSnapshot", |
| 212 method_factory_.NewRunnableMethod( | 216 method_factory_.NewRunnableMethod( |
| 213 &SyncScheduler::SendInitialSnapshot)); | 217 &SyncScheduler::SendInitialSnapshot)); |
| 214 } | 218 } |
| 215 started_ = true; | 219 started_ = true; |
| 216 // TODO(sync): This will leak if StartImpl is never run. Fix this. | |
| 217 // Might be easiest to just use base::Callback. | |
| 218 PostTask(FROM_HERE, "StartImpl", | 220 PostTask(FROM_HERE, "StartImpl", |
| 219 method_factory_.NewRunnableMethod( | 221 method_factory_.NewRunnableMethod( |
| 220 &SyncScheduler::StartImpl, mode, callback)); | 222 &SyncScheduler::StartImpl, mode, callback)); |
| 221 } | 223 } |
| 222 | 224 |
| 223 void SyncScheduler::SendInitialSnapshot() { | 225 void SyncScheduler::SendInitialSnapshot() { |
| 224 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 226 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 225 scoped_ptr<SyncSession> dummy(new SyncSession(session_context_.get(), this, | 227 scoped_ptr<SyncSession> dummy(new SyncSession(session_context_.get(), this, |
| 226 SyncSourceInfo(), ModelSafeRoutingInfo(), | 228 SyncSourceInfo(), ModelSafeRoutingInfo(), |
| 227 std::vector<ModelSafeWorker*>())); | 229 std::vector<ModelSafeWorker*>())); |
| 228 SyncEngineEvent event(SyncEngineEvent::STATUS_CHANGED); | 230 SyncEngineEvent event(SyncEngineEvent::STATUS_CHANGED); |
| 229 sessions::SyncSessionSnapshot snapshot(dummy->TakeSnapshot()); | 231 sessions::SyncSessionSnapshot snapshot(dummy->TakeSnapshot()); |
| 230 event.snapshot = &snapshot; | 232 event.snapshot = &snapshot; |
| 231 session_context_->NotifyListeners(event); | 233 session_context_->NotifyListeners(event); |
| 232 } | 234 } |
| 233 | 235 |
| 234 void SyncScheduler::WatchConnectionManager() { | 236 void SyncScheduler::WatchConnectionManager() { |
| 235 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 237 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 236 ServerConnectionManager* scm = session_context_->connection_manager(); | 238 ServerConnectionManager* scm = session_context_->connection_manager(); |
| 237 PostTask(FROM_HERE, "CheckServerConnectionManagerStatus", | 239 PostTask(FROM_HERE, "CheckServerConnectionManagerStatus", |
| 238 method_factory_.NewRunnableMethod( | 240 method_factory_.NewRunnableMethod( |
| 239 &SyncScheduler::CheckServerConnectionManagerStatus, | 241 &SyncScheduler::CheckServerConnectionManagerStatus, |
| 240 scm->server_status())); | 242 scm->server_status())); |
| 241 scm->AddListener(this); | 243 scm->AddListener(this); |
| 242 } | 244 } |
| 243 | 245 |
| 244 void SyncScheduler::StartImpl(Mode mode, ModeChangeCallback* callback) { | 246 void SyncScheduler::StartImpl(Mode mode, const base::Closure& callback) { |
| 245 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 247 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 246 SVLOG(2) << "In StartImpl with mode " << GetModeString(mode); | 248 SVLOG(2) << "In StartImpl with mode " << GetModeString(mode); |
| 247 | 249 |
| 248 scoped_ptr<ModeChangeCallback> scoped_callback(callback); | |
| 249 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 250 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 250 DCHECK(!session_context_->account_name().empty()); | 251 DCHECK(!session_context_->account_name().empty()); |
| 251 DCHECK(syncer_.get()); | 252 DCHECK(syncer_.get()); |
| 252 Mode old_mode = mode_; | 253 Mode old_mode = mode_; |
| 253 mode_ = mode; | 254 mode_ = mode; |
| 254 AdjustPolling(NULL); // Will kick start poll timer if needed. | 255 AdjustPolling(NULL); // Will kick start poll timer if needed. |
| 255 if (scoped_callback.get()) | 256 if (!callback.is_null()) |
| 256 scoped_callback->Run(); | 257 callback.Run(); |
| 257 | 258 |
| 258 if (old_mode != mode_) { | 259 if (old_mode != mode_) { |
| 259 // We just changed our mode. See if there are any pending jobs that we could | 260 // We just changed our mode. See if there are any pending jobs that we could |
| 260 // execute in the new mode. | 261 // execute in the new mode. |
| 261 DoPendingJobIfPossible(false); | 262 DoPendingJobIfPossible(false); |
| 262 } | 263 } |
| 263 } | 264 } |
| 264 | 265 |
| 265 SyncScheduler::JobProcessDecision SyncScheduler::DecideWhileInWaitInterval( | 266 SyncScheduler::JobProcessDecision SyncScheduler::DecideWhileInWaitInterval( |
| 266 const SyncSessionJob& job) { | 267 const SyncSessionJob& job) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 void SyncScheduler::InitOrCoalescePendingJob(const SyncSessionJob& job) { | 337 void SyncScheduler::InitOrCoalescePendingJob(const SyncSessionJob& job) { |
| 337 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 338 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 338 DCHECK(job.purpose != SyncSessionJob::CONFIGURATION); | 339 DCHECK(job.purpose != SyncSessionJob::CONFIGURATION); |
| 339 if (pending_nudge_.get() == NULL) { | 340 if (pending_nudge_.get() == NULL) { |
| 340 SVLOG(2) << "Creating a pending nudge job"; | 341 SVLOG(2) << "Creating a pending nudge job"; |
| 341 SyncSession* s = job.session.get(); | 342 SyncSession* s = job.session.get(); |
| 342 scoped_ptr<SyncSession> session(new SyncSession(s->context(), | 343 scoped_ptr<SyncSession> session(new SyncSession(s->context(), |
| 343 s->delegate(), s->source(), s->routing_info(), s->workers())); | 344 s->delegate(), s->source(), s->routing_info(), s->workers())); |
| 344 | 345 |
| 345 SyncSessionJob new_job(SyncSessionJob::NUDGE, job.scheduled_start, | 346 SyncSessionJob new_job(SyncSessionJob::NUDGE, job.scheduled_start, |
| 346 make_linked_ptr(session.release()), false, job.from_here); | 347 make_linked_ptr(session.release()), |
| 348 false, base::Closure(), job.from_here); |
| 347 pending_nudge_.reset(new SyncSessionJob(new_job)); | 349 pending_nudge_.reset(new SyncSessionJob(new_job)); |
| 348 | 350 |
| 349 return; | 351 return; |
| 350 } | 352 } |
| 351 | 353 |
| 352 SVLOG(2) << "Coalescing a pending nudge"; | 354 SVLOG(2) << "Coalescing a pending nudge"; |
| 353 pending_nudge_->session->Coalesce(*(job.session.get())); | 355 pending_nudge_->session->Coalesce(*(job.session.get())); |
| 354 pending_nudge_->scheduled_start = job.scheduled_start; | 356 pending_nudge_->scheduled_start = job.scheduled_start; |
| 355 | 357 |
| 356 // Unfortunately the nudge location cannot be modified. So it stores the | 358 // Unfortunately the nudge location cannot be modified. So it stores the |
| (...skipping 27 matching lines...) Expand all Loading... |
| 384 InitOrCoalescePendingJob(job); | 386 InitOrCoalescePendingJob(job); |
| 385 } else if (job.purpose == SyncSessionJob::CONFIGURATION){ | 387 } else if (job.purpose == SyncSessionJob::CONFIGURATION){ |
| 386 SVLOG(2) << "Saving a configuration job"; | 388 SVLOG(2) << "Saving a configuration job"; |
| 387 DCHECK(wait_interval_.get()); | 389 DCHECK(wait_interval_.get()); |
| 388 DCHECK(mode_ == CONFIGURATION_MODE); | 390 DCHECK(mode_ == CONFIGURATION_MODE); |
| 389 | 391 |
| 390 SyncSession* old = job.session.get(); | 392 SyncSession* old = job.session.get(); |
| 391 SyncSession* s(new SyncSession(session_context_.get(), this, | 393 SyncSession* s(new SyncSession(session_context_.get(), this, |
| 392 old->source(), old->routing_info(), old->workers())); | 394 old->source(), old->routing_info(), old->workers())); |
| 393 SyncSessionJob new_job(job.purpose, TimeTicks::Now(), | 395 SyncSessionJob new_job(job.purpose, TimeTicks::Now(), |
| 394 make_linked_ptr(s), false, job.from_here); | 396 make_linked_ptr(s), false, base::Closure(), |
| 397 job.from_here); |
| 395 wait_interval_->pending_configure_job.reset(new SyncSessionJob(new_job)); | 398 wait_interval_->pending_configure_job.reset(new SyncSessionJob(new_job)); |
| 396 } // drop the rest. | 399 } // drop the rest. |
| 397 // TODO(sync): Is it okay to drop the rest? It's weird that | 400 // TODO(sync): Is it okay to drop the rest? It's weird that |
| 398 // SaveJob() only does what it says sometimes. (See | 401 // SaveJob() only does what it says sometimes. (See |
| 399 // http://crbug.com/90868.) | 402 // http://crbug.com/90868.) |
| 400 } | 403 } |
| 401 | 404 |
| 402 // Functor for std::find_if to search by ModelSafeGroup. | 405 // Functor for std::find_if to search by ModelSafeGroup. |
| 403 struct ModelSafeWorkerGroupIs { | 406 struct ModelSafeWorkerGroupIs { |
| 404 explicit ModelSafeWorkerGroupIs(ModelSafeGroup group) : group(group) {} | 407 explicit ModelSafeWorkerGroupIs(ModelSafeGroup group) : group(group) {} |
| 405 bool operator()(ModelSafeWorker* w) { | 408 bool operator()(ModelSafeWorker* w) { |
| 406 return group == w->GetModelSafeGroup(); | 409 return group == w->GetModelSafeGroup(); |
| 407 } | 410 } |
| 408 ModelSafeGroup group; | 411 ModelSafeGroup group; |
| 409 }; | 412 }; |
| 410 | 413 |
| 411 void SyncScheduler::ScheduleClearUserData() { | 414 void SyncScheduler::ScheduleClearUserData() { |
| 412 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 415 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 413 PostTask(FROM_HERE, "ScheduleClearUserDataImpl", | 416 PostTask(FROM_HERE, "ScheduleClearUserDataImpl", |
| 414 method_factory_.NewRunnableMethod( | 417 method_factory_.NewRunnableMethod( |
| 415 &SyncScheduler::ScheduleClearUserDataImpl)); | 418 &SyncScheduler::ScheduleClearUserDataImpl)); |
| 416 } | 419 } |
| 417 | 420 |
| 418 void SyncScheduler::ScheduleCleanupDisabledTypes() { | 421 void SyncScheduler::ScheduleCleanupDisabledTypes( |
| 422 const base::Closure& callback) { |
| 419 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 423 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 420 PostTask(FROM_HERE, "ScheduleCleanupDisabledTypes", | 424 PostTask(FROM_HERE, "ScheduleCleanupDisabledTypes", |
| 421 method_factory_.NewRunnableMethod( | 425 method_factory_.NewRunnableMethod( |
| 422 &SyncScheduler::ScheduleCleanupDisabledTypesImpl)); | 426 &SyncScheduler::ScheduleCleanupDisabledTypesImpl, callback)); |
| 423 } | 427 } |
| 424 | 428 |
| 425 void SyncScheduler::ScheduleNudge( | 429 void SyncScheduler::ScheduleNudge( |
| 426 const TimeDelta& delay, | 430 const TimeDelta& delay, |
| 427 NudgeSource source, const ModelTypeBitSet& types, | 431 NudgeSource source, const ModelTypeBitSet& types, |
| 428 const tracked_objects::Location& nudge_location) { | 432 const tracked_objects::Location& nudge_location) { |
| 429 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 433 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 430 SVLOG_LOC(nudge_location, 2) | 434 SVLOG_LOC(nudge_location, 2) |
| 431 << "Nudge scheduled with delay " << delay.InMilliseconds() << " ms, " | 435 << "Nudge scheduled with delay " << delay.InMilliseconds() << " ms, " |
| 432 << "source " << GetNudgeSourceString(source) << ", " | 436 << "source " << GetNudgeSourceString(source) << ", " |
| (...skipping 23 matching lines...) Expand all Loading... |
| 456 method_factory_.NewRunnableMethod( | 460 method_factory_.NewRunnableMethod( |
| 457 &SyncScheduler::ScheduleNudgeImpl, delay, | 461 &SyncScheduler::ScheduleNudgeImpl, delay, |
| 458 GetUpdatesFromNudgeSource(source), types_with_payloads, false, | 462 GetUpdatesFromNudgeSource(source), types_with_payloads, false, |
| 459 nudge_location)); | 463 nudge_location)); |
| 460 } | 464 } |
| 461 | 465 |
| 462 void SyncScheduler::ScheduleClearUserDataImpl() { | 466 void SyncScheduler::ScheduleClearUserDataImpl() { |
| 463 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 467 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 464 ScheduleSyncSessionJob( | 468 ScheduleSyncSessionJob( |
| 465 TimeDelta::FromSeconds(0), SyncSessionJob::CLEAR_USER_DATA, | 469 TimeDelta::FromSeconds(0), SyncSessionJob::CLEAR_USER_DATA, |
| 466 CreateSyncSession(SyncSourceInfo()), FROM_HERE); | 470 CreateSyncSession(SyncSourceInfo()), base::Closure(), FROM_HERE); |
| 467 } | 471 } |
| 468 | 472 |
| 469 void SyncScheduler::ScheduleCleanupDisabledTypesImpl() { | 473 void SyncScheduler::ScheduleCleanupDisabledTypesImpl( |
| 474 const base::Closure& callback) { |
| 470 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 475 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 471 ScheduleSyncSessionJob( | 476 ScheduleSyncSessionJob( |
| 472 TimeDelta::FromSeconds(0), SyncSessionJob::CLEANUP_DISABLED_TYPES, | 477 TimeDelta::FromSeconds(0), SyncSessionJob::CLEANUP_DISABLED_TYPES, |
| 473 CreateSyncSession(SyncSourceInfo()), FROM_HERE); | 478 CreateSyncSession(SyncSourceInfo()), callback, FROM_HERE); |
| 474 } | 479 } |
| 475 | 480 |
| 476 void SyncScheduler::ScheduleNudgeImpl( | 481 void SyncScheduler::ScheduleNudgeImpl( |
| 477 const TimeDelta& delay, | 482 const TimeDelta& delay, |
| 478 GetUpdatesCallerInfo::GetUpdatesSource source, | 483 GetUpdatesCallerInfo::GetUpdatesSource source, |
| 479 const ModelTypePayloadMap& types_with_payloads, | 484 const ModelTypePayloadMap& types_with_payloads, |
| 480 bool is_canary_job, const tracked_objects::Location& nudge_location) { | 485 bool is_canary_job, const tracked_objects::Location& nudge_location) { |
| 481 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 486 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 482 | 487 |
| 483 SVLOG_LOC(nudge_location, 2) | 488 SVLOG_LOC(nudge_location, 2) |
| 484 << "In ScheduleNudgeImpl with delay " | 489 << "In ScheduleNudgeImpl with delay " |
| 485 << delay.InMilliseconds() << " ms, " | 490 << delay.InMilliseconds() << " ms, " |
| 486 << "source " << GetUpdatesSourceString(source) << ", " | 491 << "source " << GetUpdatesSourceString(source) << ", " |
| 487 << "payloads " | 492 << "payloads " |
| 488 << syncable::ModelTypePayloadMapToString(types_with_payloads) | 493 << syncable::ModelTypePayloadMapToString(types_with_payloads) |
| 489 << (is_canary_job ? " (canary)" : ""); | 494 << (is_canary_job ? " (canary)" : ""); |
| 490 | 495 |
| 491 SyncSourceInfo info(source, types_with_payloads); | 496 SyncSourceInfo info(source, types_with_payloads); |
| 492 | 497 |
| 493 SyncSession* session(CreateSyncSession(info)); | 498 SyncSession* session(CreateSyncSession(info)); |
| 494 SyncSessionJob job(SyncSessionJob::NUDGE, TimeTicks::Now() + delay, | 499 SyncSessionJob job(SyncSessionJob::NUDGE, TimeTicks::Now() + delay, |
| 495 make_linked_ptr(session), is_canary_job, | 500 make_linked_ptr(session), is_canary_job, |
| 496 nudge_location); | 501 base::Closure(), nudge_location); |
| 497 | 502 |
| 498 session = NULL; | 503 session = NULL; |
| 499 if (!ShouldRunJob(job)) | 504 if (!ShouldRunJob(job)) |
| 500 return; | 505 return; |
| 501 | 506 |
| 502 if (pending_nudge_.get()) { | 507 if (pending_nudge_.get()) { |
| 503 if (IsBackingOff() && delay > TimeDelta::FromSeconds(1)) { | 508 if (IsBackingOff() && delay > TimeDelta::FromSeconds(1)) { |
| 504 SVLOG(2) << "Dropping the nudge because we are in backoff"; | 509 SVLOG(2) << "Dropping the nudge because we are in backoff"; |
| 505 return; | 510 return; |
| 506 } | 511 } |
| 507 | 512 |
| 508 SVLOG(2) << "Coalescing pending nudge"; | 513 SVLOG(2) << "Coalescing pending nudge"; |
| 509 pending_nudge_->session->Coalesce(*(job.session.get())); | 514 pending_nudge_->session->Coalesce(*(job.session.get())); |
| 510 | 515 |
| 511 if (!IsBackingOff()) { | 516 if (!IsBackingOff()) { |
| 512 SVLOG(2) << "Dropping a nudge because" | 517 SVLOG(2) << "Dropping a nudge because" |
| 513 << " we are not in backoff and the job was coalesced"; | 518 << " we are not in backoff and the job was coalesced"; |
| 514 return; | 519 return; |
| 515 } else { | 520 } else { |
| 516 SVLOG(2) << "Rescheduling pending nudge"; | 521 SVLOG(2) << "Rescheduling pending nudge"; |
| 517 SyncSession* s = pending_nudge_->session.get(); | 522 SyncSession* s = pending_nudge_->session.get(); |
| 518 job.session.reset(new SyncSession(s->context(), s->delegate(), | 523 job.session.reset(new SyncSession(s->context(), s->delegate(), |
| 519 s->source(), s->routing_info(), s->workers())); | 524 s->source(), s->routing_info(), s->workers())); |
| 520 pending_nudge_.reset(); | 525 pending_nudge_.reset(); |
| 521 } | 526 } |
| 522 } | 527 } |
| 523 | 528 |
| 524 // TODO(lipalani) - pass the job itself to ScheduleSyncSessionJob. | 529 // TODO(lipalani) - pass the job itself to ScheduleSyncSessionJob. |
| 525 ScheduleSyncSessionJob(delay, SyncSessionJob::NUDGE, job.session.release(), | 530 ScheduleSyncSessionJob(delay, SyncSessionJob::NUDGE, job.session.release(), |
| 526 nudge_location); | 531 base::Closure(), nudge_location); |
| 527 } | 532 } |
| 528 | 533 |
| 529 // Helper to extract the routing info and workers corresponding to types in | 534 // Helper to extract the routing info and workers corresponding to types in |
| 530 // |types| from |registrar|. | 535 // |types| from |registrar|. |
| 531 void GetModelSafeParamsForTypes(const ModelTypeBitSet& types, | 536 void GetModelSafeParamsForTypes(const ModelTypeBitSet& types, |
| 532 ModelSafeWorkerRegistrar* registrar, ModelSafeRoutingInfo* routes, | 537 ModelSafeWorkerRegistrar* registrar, ModelSafeRoutingInfo* routes, |
| 533 std::vector<ModelSafeWorker*>* workers) { | 538 std::vector<ModelSafeWorker*>* workers) { |
| 534 ModelSafeRoutingInfo r_tmp; | 539 ModelSafeRoutingInfo r_tmp; |
| 535 std::vector<ModelSafeWorker*> w_tmp; | 540 std::vector<ModelSafeWorker*> w_tmp; |
| 536 registrar->GetModelSafeRoutingInfo(&r_tmp); | 541 registrar->GetModelSafeRoutingInfo(&r_tmp); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 598 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 594 | 599 |
| 595 SVLOG(2) << "In ScheduleConfigImpl"; | 600 SVLOG(2) << "In ScheduleConfigImpl"; |
| 596 // TODO(tim): config-specific GetUpdatesCallerInfo value? | 601 // TODO(tim): config-specific GetUpdatesCallerInfo value? |
| 597 SyncSession* session = new SyncSession(session_context_.get(), this, | 602 SyncSession* session = new SyncSession(session_context_.get(), this, |
| 598 SyncSourceInfo(source, | 603 SyncSourceInfo(source, |
| 599 syncable::ModelTypePayloadMapFromRoutingInfo( | 604 syncable::ModelTypePayloadMapFromRoutingInfo( |
| 600 routing_info, std::string())), | 605 routing_info, std::string())), |
| 601 routing_info, workers); | 606 routing_info, workers); |
| 602 ScheduleSyncSessionJob(TimeDelta::FromSeconds(0), | 607 ScheduleSyncSessionJob(TimeDelta::FromSeconds(0), |
| 603 SyncSessionJob::CONFIGURATION, session, FROM_HERE); | 608 SyncSessionJob::CONFIGURATION, |
| 609 session, base::Closure(), FROM_HERE); |
| 604 } | 610 } |
| 605 | 611 |
| 606 const char* SyncScheduler::GetModeString(SyncScheduler::Mode mode) { | 612 const char* SyncScheduler::GetModeString(SyncScheduler::Mode mode) { |
| 607 switch (mode) { | 613 switch (mode) { |
| 608 ENUM_CASE(CONFIGURATION_MODE); | 614 ENUM_CASE(CONFIGURATION_MODE); |
| 609 ENUM_CASE(NORMAL_MODE); | 615 ENUM_CASE(NORMAL_MODE); |
| 610 } | 616 } |
| 611 return ""; | 617 return ""; |
| 612 } | 618 } |
| 613 | 619 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 633 const char* name, Task* task, int64 delay_ms) { | 639 const char* name, Task* task, int64 delay_ms) { |
| 634 SVLOG_LOC(from_here, 3) << "Posting " << name << " task with " | 640 SVLOG_LOC(from_here, 3) << "Posting " << name << " task with " |
| 635 << delay_ms << " ms delay"; | 641 << delay_ms << " ms delay"; |
| 636 sync_loop_->PostDelayedTask(from_here, task, delay_ms); | 642 sync_loop_->PostDelayedTask(from_here, task, delay_ms); |
| 637 } | 643 } |
| 638 | 644 |
| 639 void SyncScheduler::ScheduleSyncSessionJob( | 645 void SyncScheduler::ScheduleSyncSessionJob( |
| 640 const base::TimeDelta& delay, | 646 const base::TimeDelta& delay, |
| 641 SyncSessionJob::SyncSessionJobPurpose purpose, | 647 SyncSessionJob::SyncSessionJobPurpose purpose, |
| 642 sessions::SyncSession* session, | 648 sessions::SyncSession* session, |
| 649 const base::Closure& on_success, |
| 643 const tracked_objects::Location& from_here) { | 650 const tracked_objects::Location& from_here) { |
| 644 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 651 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 645 SVLOG_LOC(from_here, 2) | 652 SVLOG_LOC(from_here, 2) |
| 646 << "In ScheduleSyncSessionJob with " | 653 << "In ScheduleSyncSessionJob with " |
| 647 << SyncSessionJob::GetPurposeString(purpose) | 654 << SyncSessionJob::GetPurposeString(purpose) |
| 648 << " job and " << delay.InMilliseconds() << " ms delay"; | 655 << " job and " << delay.InMilliseconds() << " ms delay"; |
| 649 | 656 |
| 650 SyncSessionJob job(purpose, TimeTicks::Now() + delay, | 657 SyncSessionJob job(purpose, TimeTicks::Now() + delay, |
| 651 make_linked_ptr(session), false, from_here); | 658 make_linked_ptr(session), false, on_success, from_here); |
| 652 if (purpose == SyncSessionJob::NUDGE) { | 659 if (purpose == SyncSessionJob::NUDGE) { |
| 653 SVLOG_LOC(from_here, 2) << "Resetting pending_nudge"; | 660 SVLOG_LOC(from_here, 2) << "Resetting pending_nudge"; |
| 654 DCHECK(!pending_nudge_.get() || pending_nudge_->session.get() == session); | 661 DCHECK(!pending_nudge_.get() || pending_nudge_->session.get() == session); |
| 655 pending_nudge_.reset(new SyncSessionJob(job)); | 662 pending_nudge_.reset(new SyncSessionJob(job)); |
| 656 } | 663 } |
| 657 PostDelayedTask(from_here, "DoSyncSessionJob", | 664 PostDelayedTask(from_here, "DoSyncSessionJob", |
| 658 method_factory_.NewRunnableMethod( | 665 method_factory_.NewRunnableMethod( |
| 659 &SyncScheduler::DoSyncSessionJob, job), | 666 &SyncScheduler::DoSyncSessionJob, job), |
| 660 delay.InMilliseconds()); | 667 delay.InMilliseconds()); |
| 661 } | 668 } |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 if (IsSyncingCurrentlySilenced()) { | 782 if (IsSyncingCurrentlySilenced()) { |
| 776 SVLOG(2) << "We are currently throttled; not scheduling the next sync."; | 783 SVLOG(2) << "We are currently throttled; not scheduling the next sync."; |
| 777 // TODO(sync): Investigate whether we need to check job.purpose | 784 // TODO(sync): Investigate whether we need to check job.purpose |
| 778 // here; see DCHECKs in SaveJob(). (See http://crbug.com/90868.) | 785 // here; see DCHECKs in SaveJob(). (See http://crbug.com/90868.) |
| 779 SaveJob(job); | 786 SaveJob(job); |
| 780 return; // Nothing to do. | 787 return; // Nothing to do. |
| 781 } | 788 } |
| 782 | 789 |
| 783 SVLOG(2) << "Updating the next polling time after SyncMain"; | 790 SVLOG(2) << "Updating the next polling time after SyncMain"; |
| 784 ScheduleNextSync(job); | 791 ScheduleNextSync(job); |
| 792 if (!job.on_success.is_null()) |
| 793 job.on_success.Run(); |
| 785 } | 794 } |
| 786 | 795 |
| 787 void SyncScheduler::ScheduleNextSync(const SyncSessionJob& old_job) { | 796 void SyncScheduler::ScheduleNextSync(const SyncSessionJob& old_job) { |
| 788 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 797 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 789 DCHECK(!old_job.session->HasMoreToSync()); | 798 DCHECK(!old_job.session->HasMoreToSync()); |
| 790 // Note: |num_server_changes_remaining| > 0 here implies that we received a | 799 // Note: |num_server_changes_remaining| > 0 here implies that we received a |
| 791 // broken response while trying to download all updates, because the Syncer | 800 // broken response while trying to download all updates, because the Syncer |
| 792 // will loop until this value is exhausted. Also, if unsynced_handles exist | 801 // will loop until this value is exhausted. Also, if unsynced_handles exist |
| 793 // but HasMoreToSync is false, this implies that the Syncer determined no | 802 // but HasMoreToSync is false, this implies that the Syncer determined no |
| 794 // forward progress was possible at this time (an error, such as an HTTP | 803 // forward progress was possible at this time (an error, such as an HTTP |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 << length.InMilliseconds(); | 912 << length.InMilliseconds(); |
| 904 | 913 |
| 905 // This will reset the had_nudge variable as well. | 914 // This will reset the had_nudge variable as well. |
| 906 wait_interval_.reset(new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, | 915 wait_interval_.reset(new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, |
| 907 length)); | 916 length)); |
| 908 if (old_job.purpose == SyncSessionJob::CONFIGURATION) { | 917 if (old_job.purpose == SyncSessionJob::CONFIGURATION) { |
| 909 SyncSession* old = old_job.session.get(); | 918 SyncSession* old = old_job.session.get(); |
| 910 SyncSession* s(new SyncSession(session_context_.get(), this, | 919 SyncSession* s(new SyncSession(session_context_.get(), this, |
| 911 old->source(), old->routing_info(), old->workers())); | 920 old->source(), old->routing_info(), old->workers())); |
| 912 SyncSessionJob job(old_job.purpose, TimeTicks::Now() + length, | 921 SyncSessionJob job(old_job.purpose, TimeTicks::Now() + length, |
| 913 make_linked_ptr(s), false, FROM_HERE); | 922 make_linked_ptr(s), false, base::Closure(), |
| 923 FROM_HERE); |
| 914 wait_interval_->pending_configure_job.reset(new SyncSessionJob(job)); | 924 wait_interval_->pending_configure_job.reset(new SyncSessionJob(job)); |
| 915 } else { | 925 } else { |
| 916 // We are not in configuration mode. So wait_interval's pending job | 926 // We are not in configuration mode. So wait_interval's pending job |
| 917 // should be null. | 927 // should be null. |
| 918 DCHECK(wait_interval_->pending_configure_job.get() == NULL); | 928 DCHECK(wait_interval_->pending_configure_job.get() == NULL); |
| 919 | 929 |
| 920 // TODO(lipalani) - handle clear user data. | 930 // TODO(lipalani) - handle clear user data. |
| 921 InitOrCoalescePendingJob(old_job); | 931 InitOrCoalescePendingJob(old_job); |
| 922 } | 932 } |
| 923 RestartWaiting(); | 933 RestartWaiting(); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 copy.is_canary_job = is_canary_job; | 1009 copy.is_canary_job = is_canary_job; |
| 1000 DoSyncSessionJob(copy); | 1010 DoSyncSessionJob(copy); |
| 1001 } | 1011 } |
| 1002 } | 1012 } |
| 1003 | 1013 |
| 1004 SyncSession* SyncScheduler::CreateSyncSession(const SyncSourceInfo& source) { | 1014 SyncSession* SyncScheduler::CreateSyncSession(const SyncSourceInfo& source) { |
| 1005 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1015 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1006 ModelSafeRoutingInfo routes; | 1016 ModelSafeRoutingInfo routes; |
| 1007 std::vector<ModelSafeWorker*> workers; | 1017 std::vector<ModelSafeWorker*> workers; |
| 1008 session_context_->registrar()->GetModelSafeRoutingInfo(&routes); | 1018 session_context_->registrar()->GetModelSafeRoutingInfo(&routes); |
| 1019 VLOG(2) << "Creating sync session with routes " |
| 1020 << ModelSafeRoutingInfoToString(routes); |
| 1009 session_context_->registrar()->GetWorkers(&workers); | 1021 session_context_->registrar()->GetWorkers(&workers); |
| 1010 SyncSourceInfo info(source); | 1022 SyncSourceInfo info(source); |
| 1011 | 1023 |
| 1012 SyncSession* session(new SyncSession(session_context_.get(), this, info, | 1024 SyncSession* session(new SyncSession(session_context_.get(), this, info, |
| 1013 routes, workers)); | 1025 routes, workers)); |
| 1014 | 1026 |
| 1015 return session; | 1027 return session; |
| 1016 } | 1028 } |
| 1017 | 1029 |
| 1018 void SyncScheduler::PollTimerCallback() { | 1030 void SyncScheduler::PollTimerCallback() { |
| 1019 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1031 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1020 ModelSafeRoutingInfo r; | 1032 ModelSafeRoutingInfo r; |
| 1021 ModelTypePayloadMap types_with_payloads = | 1033 ModelTypePayloadMap types_with_payloads = |
| 1022 syncable::ModelTypePayloadMapFromRoutingInfo(r, std::string()); | 1034 syncable::ModelTypePayloadMapFromRoutingInfo(r, std::string()); |
| 1023 SyncSourceInfo info(GetUpdatesCallerInfo::PERIODIC, types_with_payloads); | 1035 SyncSourceInfo info(GetUpdatesCallerInfo::PERIODIC, types_with_payloads); |
| 1024 SyncSession* s = CreateSyncSession(info); | 1036 SyncSession* s = CreateSyncSession(info); |
| 1025 ScheduleSyncSessionJob(TimeDelta::FromSeconds(0), SyncSessionJob::POLL, s, | 1037 ScheduleSyncSessionJob(TimeDelta::FromSeconds(0), SyncSessionJob::POLL, s, |
| 1026 FROM_HERE); | 1038 base::Closure(), FROM_HERE); |
| 1027 } | 1039 } |
| 1028 | 1040 |
| 1029 void SyncScheduler::Unthrottle() { | 1041 void SyncScheduler::Unthrottle() { |
| 1030 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1042 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1031 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode); | 1043 DCHECK_EQ(WaitInterval::THROTTLED, wait_interval_->mode); |
| 1032 SVLOG(2) << "Unthrottled."; | 1044 SVLOG(2) << "Unthrottled."; |
| 1033 DoCanaryJob(); | 1045 DoCanaryJob(); |
| 1034 wait_interval_.reset(); | 1046 wait_interval_.reset(); |
| 1035 } | 1047 } |
| 1036 | 1048 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1105 | 1117 |
| 1106 #undef SVLOG_LOC | 1118 #undef SVLOG_LOC |
| 1107 | 1119 |
| 1108 #undef SVLOG | 1120 #undef SVLOG |
| 1109 | 1121 |
| 1110 #undef SLOG | 1122 #undef SLOG |
| 1111 | 1123 |
| 1112 #undef ENUM_CASE | 1124 #undef ENUM_CASE |
| 1113 | 1125 |
| 1114 } // browser_sync | 1126 } // browser_sync |
| OLD | NEW |