| 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 "sync/engine/sync_scheduler_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 | 9 |
| 10 #include "base/auto_reset.h" |
| 10 #include "base/bind.h" | 11 #include "base/bind.h" |
| 11 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 12 #include "base/location.h" | 13 #include "base/location.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
| 15 #include "sync/engine/backoff_delay_provider.h" | 16 #include "sync/engine/backoff_delay_provider.h" |
| 16 #include "sync/engine/syncer.h" | 17 #include "sync/engine/syncer.h" |
| 17 #include "sync/engine/throttled_data_type_tracker.h" | 18 #include "sync/engine/throttled_data_type_tracker.h" |
| 18 #include "sync/protocol/proto_enum_conversions.h" | 19 #include "sync/protocol/proto_enum_conversions.h" |
| 19 #include "sync/protocol/sync.pb.h" | 20 #include "sync/protocol/sync.pb.h" |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 syncer_long_poll_interval_seconds_( | 200 syncer_long_poll_interval_seconds_( |
| 200 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)), | 201 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)), |
| 201 sessions_commit_delay_( | 202 sessions_commit_delay_( |
| 202 TimeDelta::FromSeconds(kDefaultSessionsCommitDelaySeconds)), | 203 TimeDelta::FromSeconds(kDefaultSessionsCommitDelaySeconds)), |
| 203 mode_(NORMAL_MODE), | 204 mode_(NORMAL_MODE), |
| 204 // Start with assuming everything is fine with the connection. | 205 // Start with assuming everything is fine with the connection. |
| 205 // At the end of the sync cycle we would have the correct status. | 206 // At the end of the sync cycle we would have the correct status. |
| 206 connection_code_(HttpResponse::SERVER_CONNECTION_OK), | 207 connection_code_(HttpResponse::SERVER_CONNECTION_OK), |
| 207 delay_provider_(delay_provider), | 208 delay_provider_(delay_provider), |
| 208 syncer_(syncer), | 209 syncer_(syncer), |
| 209 session_context_(context) { | 210 session_context_(context), |
| 211 no_scheduling_allowed_(false) { |
| 210 DCHECK(sync_loop_); | 212 DCHECK(sync_loop_); |
| 211 } | 213 } |
| 212 | 214 |
| 213 SyncSchedulerImpl::~SyncSchedulerImpl() { | 215 SyncSchedulerImpl::~SyncSchedulerImpl() { |
| 214 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 216 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 215 StopImpl(base::Closure()); | 217 StopImpl(base::Closure()); |
| 216 } | 218 } |
| 217 | 219 |
| 218 void SyncSchedulerImpl::OnCredentialsUpdated() { | 220 void SyncSchedulerImpl::OnCredentialsUpdated() { |
| 219 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 221 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 | 270 |
| 269 DCHECK(!session_context_->account_name().empty()); | 271 DCHECK(!session_context_->account_name().empty()); |
| 270 DCHECK(syncer_.get()); | 272 DCHECK(syncer_.get()); |
| 271 Mode old_mode = mode_; | 273 Mode old_mode = mode_; |
| 272 mode_ = mode; | 274 mode_ = mode; |
| 273 AdjustPolling(NULL); // Will kick start poll timer if needed. | 275 AdjustPolling(NULL); // Will kick start poll timer if needed. |
| 274 | 276 |
| 275 if (old_mode != mode_) { | 277 if (old_mode != mode_) { |
| 276 // We just changed our mode. See if there are any pending jobs that we could | 278 // We just changed our mode. See if there are any pending jobs that we could |
| 277 // execute in the new mode. | 279 // execute in the new mode. |
| 280 if (mode_ == NORMAL_MODE) { |
| 281 // It is illegal to switch to NORMAL_MODE if a previous CONFIGURATION job |
| 282 // has not yet completed. |
| 283 DCHECK(!wait_interval_.get() || |
| 284 !wait_interval_->pending_configure_job.get()); |
| 285 } |
| 286 |
| 278 DoPendingJobIfPossible(false); | 287 DoPendingJobIfPossible(false); |
| 279 } | 288 } |
| 280 } | 289 } |
| 281 | 290 |
| 282 void SyncSchedulerImpl::SendInitialSnapshot() { | 291 void SyncSchedulerImpl::SendInitialSnapshot() { |
| 283 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 292 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 284 scoped_ptr<SyncSession> dummy(new SyncSession(session_context_, this, | 293 scoped_ptr<SyncSession> dummy(new SyncSession(session_context_, this, |
| 285 SyncSourceInfo(), ModelSafeRoutingInfo(), | 294 SyncSourceInfo(), ModelSafeRoutingInfo(), |
| 286 std::vector<ModelSafeWorker*>())); | 295 std::vector<ModelSafeWorker*>())); |
| 287 SyncEngineEvent event(SyncEngineEvent::STATUS_CHANGED); | 296 SyncEngineEvent event(SyncEngineEvent::STATUS_CHANGED); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 else if (job.purpose == SyncSessionJob::CONFIGURATION) | 452 else if (job.purpose == SyncSessionJob::CONFIGURATION) |
| 444 return CONTINUE; | 453 return CONTINUE; |
| 445 else | 454 else |
| 446 return DROP; | 455 return DROP; |
| 447 } | 456 } |
| 448 | 457 |
| 449 // We are in normal mode. | 458 // We are in normal mode. |
| 450 DCHECK_EQ(mode_, NORMAL_MODE); | 459 DCHECK_EQ(mode_, NORMAL_MODE); |
| 451 DCHECK_NE(job.purpose, SyncSessionJob::CONFIGURATION); | 460 DCHECK_NE(job.purpose, SyncSessionJob::CONFIGURATION); |
| 452 | 461 |
| 453 // Freshness condition | 462 // Note about some subtle scheduling semantics. |
| 454 if (job.scheduled_start < last_sync_session_end_time_) { | 463 // |
| 455 SDVLOG(2) << "Dropping job because of freshness"; | 464 // It's possible at this point that |job| is known to be unnecessary, and |
| 456 return DROP; | 465 // dropping it would be perfectly safe and correct. Consider |
| 457 } | 466 // |
| 467 // 1) |job| is a POLL with a |scheduled_start| time that is less than |
| 468 // the time that the last successful all-datatype NUDGE completed. |
| 469 // |
| 470 // 2) |job| is a NUDGE (for any combination of types) with a |
| 471 // |scheduled_start| time that is less than the time that the last |
| 472 // successful all-datatype NUDGE completed, and it has a NOTIFICATION |
| 473 // GetUpdatesCallerInfo value yet offers no new notification hint. |
| 474 // |
| 475 // 3) |job| is a NUDGE with a |scheduled_start| time that is less than |
| 476 // the time that the last successful matching-datatype NUDGE completed, |
| 477 // and payloads (hints) are identical to that last successful NUDGE. |
| 478 // |
| 479 // Case 1 can occur if the POLL timer fires *after* a call to |
| 480 // ScheduleSyncSessionJob for a NUDGE, but *before* the thread actually |
| 481 // picks the resulting posted task off of the MessageLoop. The NUDGE will |
| 482 // run first and complete at a time greater than the POLL scheduled_start. |
| 483 // However, this case (and POLLs in general) is so rare that we ignore it ( |
| 484 // and avoid the required bookeeping to simplify code). |
| 485 // |
| 486 // We avoid cases 2 and 3 by externally synchronizing NUDGE requests -- |
| 487 // scheduling a NUDGE requires command of the sync thread, which is |
| 488 // impossible* from outside of SyncScheduler if a NUDGE is taking place. |
| 489 // And if you have command of the sync thread when scheduling a NUDGE and a |
| 490 // previous NUDGE exists, they will be coalesced and the stale job will be |
| 491 // cancelled via the session-equality check in DoSyncSessionJob. |
| 492 // |
| 493 // * It's not strictly "impossible", but it would be reentrant and hence |
| 494 // illegal. e.g. scheduling a job and re-entering the SyncScheduler is NOT a |
| 495 // legal side effect of any of the work being done as part of a sync cycle. |
| 496 // See |no_scheduling_allowed_| for details. |
| 458 | 497 |
| 498 // Decision now rests on state of auth tokens. |
| 459 if (!session_context_->connection_manager()->HasInvalidAuthToken()) | 499 if (!session_context_->connection_manager()->HasInvalidAuthToken()) |
| 460 return CONTINUE; | 500 return CONTINUE; |
| 461 | 501 |
| 462 SDVLOG(2) << "No valid auth token. Using that to decide on job."; | 502 SDVLOG(2) << "No valid auth token. Using that to decide on job."; |
| 463 return job.purpose == SyncSessionJob::NUDGE ? SAVE : DROP; | 503 return job.purpose == SyncSessionJob::NUDGE ? SAVE : DROP; |
| 464 } | 504 } |
| 465 | 505 |
| 466 void SyncSchedulerImpl::InitOrCoalescePendingJob(const SyncSessionJob& job) { | 506 void SyncSchedulerImpl::InitOrCoalescePendingJob(const SyncSessionJob& job) { |
| 467 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 507 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 468 DCHECK(job.purpose != SyncSessionJob::CONFIGURATION); | 508 DCHECK(job.purpose != SyncSessionJob::CONFIGURATION); |
| 469 if (pending_nudge_.get() == NULL) { | 509 if (pending_nudge_.get() == NULL) { |
| 470 SDVLOG(2) << "Creating a pending nudge job"; | 510 SDVLOG(2) << "Creating a pending nudge job"; |
| 471 SyncSession* s = job.session.get(); | 511 SyncSession* s = job.session.get(); |
| 512 |
| 513 // Get a fresh session with similar configuration as before (resets |
| 514 // StatusController). |
| 472 scoped_ptr<SyncSession> session(new SyncSession(s->context(), | 515 scoped_ptr<SyncSession> session(new SyncSession(s->context(), |
| 473 s->delegate(), s->source(), s->routing_info(), s->workers())); | 516 s->delegate(), s->source(), s->routing_info(), s->workers())); |
| 474 | 517 |
| 475 SyncSessionJob new_job(SyncSessionJob::NUDGE, job.scheduled_start, | 518 SyncSessionJob new_job(SyncSessionJob::NUDGE, job.scheduled_start, |
| 476 make_linked_ptr(session.release()), false, | 519 make_linked_ptr(session.release()), false, |
| 477 ConfigurationParams(), job.from_here); | 520 ConfigurationParams(), job.from_here); |
| 478 pending_nudge_.reset(new SyncSessionJob(new_job)); | 521 pending_nudge_.reset(new SyncSessionJob(new_job)); |
| 479 | |
| 480 return; | 522 return; |
| 481 } | 523 } |
| 482 | 524 |
| 483 SDVLOG(2) << "Coalescing a pending nudge"; | 525 SDVLOG(2) << "Coalescing a pending nudge"; |
| 484 pending_nudge_->session->Coalesce(*(job.session.get())); | 526 pending_nudge_->session->Coalesce(*(job.session.get())); |
| 485 pending_nudge_->scheduled_start = job.scheduled_start; | 527 pending_nudge_->scheduled_start = job.scheduled_start; |
| 486 | 528 |
| 487 // Unfortunately the nudge location cannot be modified. So it stores the | 529 // Unfortunately the nudge location cannot be modified. So it stores the |
| 488 // location of the first caller. | 530 // location of the first caller. |
| 489 } | 531 } |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 false, | 622 false, |
| 581 nudge_location); | 623 nudge_location); |
| 582 } | 624 } |
| 583 | 625 |
| 584 void SyncSchedulerImpl::ScheduleNudgeImpl( | 626 void SyncSchedulerImpl::ScheduleNudgeImpl( |
| 585 const TimeDelta& delay, | 627 const TimeDelta& delay, |
| 586 GetUpdatesCallerInfo::GetUpdatesSource source, | 628 GetUpdatesCallerInfo::GetUpdatesSource source, |
| 587 const ModelTypeStateMap& type_state_map, | 629 const ModelTypeStateMap& type_state_map, |
| 588 bool is_canary_job, const tracked_objects::Location& nudge_location) { | 630 bool is_canary_job, const tracked_objects::Location& nudge_location) { |
| 589 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 631 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 632 DCHECK(!type_state_map.empty()) << "Nudge scheduled for no types!"; |
| 590 | 633 |
| 591 SDVLOG_LOC(nudge_location, 2) | 634 SDVLOG_LOC(nudge_location, 2) |
| 592 << "In ScheduleNudgeImpl with delay " | 635 << "In ScheduleNudgeImpl with delay " |
| 593 << delay.InMilliseconds() << " ms, " | 636 << delay.InMilliseconds() << " ms, " |
| 594 << "source " << GetUpdatesSourceString(source) << ", " | 637 << "source " << GetUpdatesSourceString(source) << ", " |
| 595 << "payloads " | 638 << "payloads " |
| 596 << ModelTypeStateMapToString(type_state_map) | 639 << ModelTypeStateMapToString(type_state_map) |
| 597 << (is_canary_job ? " (canary)" : ""); | 640 << (is_canary_job ? " (canary)" : ""); |
| 598 | 641 |
| 599 SyncSourceInfo info(source, type_state_map); | 642 SyncSourceInfo info(source, type_state_map); |
| 643 UpdateNudgeTimeRecords(info); |
| 600 | 644 |
| 601 SyncSession* session(CreateSyncSession(info)); | 645 SyncSession* session(CreateSyncSession(info)); |
| 602 SyncSessionJob job(SyncSessionJob::NUDGE, TimeTicks::Now() + delay, | 646 SyncSessionJob job(SyncSessionJob::NUDGE, TimeTicks::Now() + delay, |
| 603 make_linked_ptr(session), is_canary_job, | 647 make_linked_ptr(session), is_canary_job, |
| 604 ConfigurationParams(), nudge_location); | 648 ConfigurationParams(), nudge_location); |
| 605 | 649 |
| 606 session = NULL; | 650 session = NULL; |
| 607 if (!ShouldRunJob(job)) | 651 if (!ShouldRunJob(job)) |
| 608 return; | 652 return; |
| 609 | 653 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 737 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 694 if (!started_) { | 738 if (!started_) { |
| 695 SDVLOG(1) << "Not posting task as scheduler is stopped."; | 739 SDVLOG(1) << "Not posting task as scheduler is stopped."; |
| 696 return; | 740 return; |
| 697 } | 741 } |
| 698 sync_loop_->PostDelayedTask(from_here, task, delay); | 742 sync_loop_->PostDelayedTask(from_here, task, delay); |
| 699 } | 743 } |
| 700 | 744 |
| 701 void SyncSchedulerImpl::ScheduleSyncSessionJob(const SyncSessionJob& job) { | 745 void SyncSchedulerImpl::ScheduleSyncSessionJob(const SyncSessionJob& job) { |
| 702 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 746 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 747 if (no_scheduling_allowed_) { |
| 748 NOTREACHED() << "Illegal to schedule job while session in progress."; |
| 749 return; |
| 750 } |
| 751 |
| 703 TimeDelta delay = job.scheduled_start - TimeTicks::Now(); | 752 TimeDelta delay = job.scheduled_start - TimeTicks::Now(); |
| 704 if (delay < TimeDelta::FromMilliseconds(0)) | 753 if (delay < TimeDelta::FromMilliseconds(0)) |
| 705 delay = TimeDelta::FromMilliseconds(0); | 754 delay = TimeDelta::FromMilliseconds(0); |
| 706 SDVLOG_LOC(job.from_here, 2) | 755 SDVLOG_LOC(job.from_here, 2) |
| 707 << "In ScheduleSyncSessionJob with " | 756 << "In ScheduleSyncSessionJob with " |
| 708 << SyncSessionJob::GetPurposeString(job.purpose) | 757 << SyncSessionJob::GetPurposeString(job.purpose) |
| 709 << " job and " << delay.InMilliseconds() << " ms delay"; | 758 << " job and " << delay.InMilliseconds() << " ms delay"; |
| 710 | 759 |
| 711 DCHECK(job.purpose == SyncSessionJob::NUDGE || | 760 DCHECK(job.purpose == SyncSessionJob::NUDGE || |
| 712 job.purpose == SyncSessionJob::POLL); | 761 job.purpose == SyncSessionJob::POLL); |
| 713 if (job.purpose == SyncSessionJob::NUDGE) { | 762 if (job.purpose == SyncSessionJob::NUDGE) { |
| 714 SDVLOG_LOC(job.from_here, 2) << "Resetting pending_nudge"; | 763 SDVLOG_LOC(job.from_here, 2) << "Resetting pending_nudge"; |
| 715 DCHECK(!pending_nudge_.get() || pending_nudge_->session.get() == | 764 DCHECK(!pending_nudge_.get() || pending_nudge_->session.get() == |
| 716 job.session); | 765 job.session); |
| 717 pending_nudge_.reset(new SyncSessionJob(job)); | 766 pending_nudge_.reset(new SyncSessionJob(job)); |
| 718 } | 767 } |
| 719 PostDelayedTask(job.from_here, "DoSyncSessionJob", | 768 PostDelayedTask(job.from_here, "DoSyncSessionJob", |
| 720 base::Bind(&SyncSchedulerImpl::DoSyncSessionJob, | 769 base::Bind(&SyncSchedulerImpl::DoSyncSessionJob, |
| 721 weak_ptr_factory_.GetWeakPtr(), | 770 weak_ptr_factory_.GetWeakPtr(), |
| 722 job), | 771 job), |
| 723 delay); | 772 delay); |
| 724 } | 773 } |
| 725 | 774 |
| 726 void SyncSchedulerImpl::DoSyncSessionJob(const SyncSessionJob& job) { | 775 void SyncSchedulerImpl::DoSyncSessionJob(const SyncSessionJob& job) { |
| 727 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 776 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 777 |
| 778 AutoReset<bool> protector(&no_scheduling_allowed_, true); |
| 728 if (!ShouldRunJob(job)) { | 779 if (!ShouldRunJob(job)) { |
| 729 SLOG(WARNING) | 780 SLOG(WARNING) |
| 730 << "Not executing " | 781 << "Not executing " |
| 731 << SyncSessionJob::GetPurposeString(job.purpose) << " job from " | 782 << SyncSessionJob::GetPurposeString(job.purpose) << " job from " |
| 732 << GetUpdatesSourceString(job.session->source().updates_source); | 783 << GetUpdatesSourceString(job.session->source().updates_source); |
| 733 return; | 784 return; |
| 734 } | 785 } |
| 735 | 786 |
| 736 if (job.purpose == SyncSessionJob::NUDGE) { | 787 if (job.purpose == SyncSessionJob::NUDGE) { |
| 737 if (pending_nudge_.get() == NULL || | 788 if (pending_nudge_.get() == NULL || |
| (...skipping 24 matching lines...) Expand all Loading... |
| 762 syncer_->SyncShare(job.session.get(), begin, end); | 813 syncer_->SyncShare(job.session.get(), begin, end); |
| 763 has_more_to_sync = job.session->HasMoreToSync(); | 814 has_more_to_sync = job.session->HasMoreToSync(); |
| 764 if (has_more_to_sync) | 815 if (has_more_to_sync) |
| 765 job.session->PrepareForAnotherSyncCycle(); | 816 job.session->PrepareForAnotherSyncCycle(); |
| 766 } | 817 } |
| 767 SDVLOG(2) << "Done SyncShare looping."; | 818 SDVLOG(2) << "Done SyncShare looping."; |
| 768 | 819 |
| 769 FinishSyncSessionJob(job); | 820 FinishSyncSessionJob(job); |
| 770 } | 821 } |
| 771 | 822 |
| 823 void SyncSchedulerImpl::UpdateNudgeTimeRecords(const SyncSourceInfo& info) { |
| 824 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 825 |
| 826 // We are interested in recording time between local nudges for datatypes. |
| 827 // TODO(tim): Consider tracking LOCAL_NOTIFICATION as well. |
| 828 if (info.updates_source != GetUpdatesCallerInfo::LOCAL) |
| 829 return; |
| 830 |
| 831 base::TimeTicks now = TimeTicks::Now(); |
| 832 // Update timing information for how often datatypes are triggering nudges. |
| 833 for (ModelTypeStateMap::const_iterator iter = info.types.begin(); |
| 834 iter != info.types.end(); |
| 835 ++iter) { |
| 836 base::TimeTicks previous = last_local_nudges_by_model_type_[iter->first]; |
| 837 last_local_nudges_by_model_type_[iter->first] = now; |
| 838 if (previous.is_null()) |
| 839 continue; |
| 840 |
| 841 #define PER_DATA_TYPE_MACRO(type_str) \ |
| 842 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); |
| 843 SYNC_DATA_TYPE_HISTOGRAM(iter->first); |
| 844 #undef PER_DATA_TYPE_MACRO |
| 845 } |
| 846 } |
| 847 |
| 772 void SyncSchedulerImpl::FinishSyncSessionJob(const SyncSessionJob& job) { | 848 void SyncSchedulerImpl::FinishSyncSessionJob(const SyncSessionJob& job) { |
| 773 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 849 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 774 // Update timing information for how often datatypes are triggering nudges. | |
| 775 base::TimeTicks now = TimeTicks::Now(); | |
| 776 if (!last_sync_session_end_time_.is_null()) { | |
| 777 ModelTypeStateMap::const_iterator iter; | |
| 778 for (iter = job.session->source().types.begin(); | |
| 779 iter != job.session->source().types.end(); | |
| 780 ++iter) { | |
| 781 #define PER_DATA_TYPE_MACRO(type_str) \ | |
| 782 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, \ | |
| 783 now - last_sync_session_end_time_); | |
| 784 SYNC_DATA_TYPE_HISTOGRAM(iter->first); | |
| 785 #undef PER_DATA_TYPE_MACRO | |
| 786 } | |
| 787 } | |
| 788 last_sync_session_end_time_ = now; | |
| 789 | |
| 790 // Now update the status of the connection from SCM. We need this to decide | 850 // Now update the status of the connection from SCM. We need this to decide |
| 791 // whether we need to save/run future jobs. The notifications from SCM are not | 851 // whether we need to save/run future jobs. The notifications from SCM are not |
| 792 // reliable. | 852 // reliable. |
| 793 // | 853 // |
| 794 // TODO(rlarocque): crbug.com/110954 | 854 // TODO(rlarocque): crbug.com/110954 |
| 795 // We should get rid of the notifications and it is probably not needed to | 855 // We should get rid of the notifications and it is probably not needed to |
| 796 // maintain this status variable in 2 places. We should query it directly from | 856 // maintain this status variable in 2 places. We should query it directly from |
| 797 // SCM when needed. | 857 // SCM when needed. |
| 798 ServerConnectionManager* scm = session_context_->connection_manager(); | 858 ServerConnectionManager* scm = session_context_->connection_manager(); |
| 799 UpdateServerConnectionManagerStatus(scm->server_status()); | 859 UpdateServerConnectionManagerStatus(scm->server_status()); |
| 800 | 860 |
| 801 if (IsSyncingCurrentlySilenced()) { | 861 if (IsSyncingCurrentlySilenced()) { |
| 802 SDVLOG(2) << "We are currently throttled; not scheduling the next sync."; | 862 SDVLOG(2) << "We are currently throttled; not scheduling the next sync."; |
| 803 // TODO(sync): Investigate whether we need to check job.purpose | 863 // TODO(sync): Investigate whether we need to check job.purpose |
| 804 // here; see DCHECKs in SaveJob(). (See http://crbug.com/90868.) | 864 // here; see DCHECKs in SaveJob(). (See http://crbug.com/90868.) |
| 805 SaveJob(job); | 865 SaveJob(job); |
| 806 return; // Nothing to do. | 866 return; // Nothing to do. |
| 807 } else if (job.session->Succeeded() && | 867 } else if (job.session->Succeeded() && |
| 808 !job.config_params.ready_task.is_null()) { | 868 !job.config_params.ready_task.is_null()) { |
| 809 // If this was a configuration job with a ready task, invoke it now that | 869 // If this was a configuration job with a ready task, invoke it now that |
| 810 // we finished successfully. | 870 // we finished successfully. |
| 871 AutoReset<bool> protector(&no_scheduling_allowed_, true); |
| 811 job.config_params.ready_task.Run(); | 872 job.config_params.ready_task.Run(); |
| 812 } | 873 } |
| 813 | 874 |
| 814 SDVLOG(2) << "Updating the next polling time after SyncMain"; | 875 SDVLOG(2) << "Updating the next polling time after SyncMain"; |
| 815 ScheduleNextSync(job); | 876 ScheduleNextSync(job); |
| 816 } | 877 } |
| 817 | 878 |
| 818 void SyncSchedulerImpl::ScheduleNextSync(const SyncSessionJob& old_job) { | 879 void SyncSchedulerImpl::ScheduleNextSync(const SyncSessionJob& old_job) { |
| 819 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 880 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 820 DCHECK(!old_job.session->HasMoreToSync()); | 881 DCHECK(!old_job.session->HasMoreToSync()); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 | 1028 |
| 968 void SyncSchedulerImpl::DoPendingJobIfPossible(bool is_canary_job) { | 1029 void SyncSchedulerImpl::DoPendingJobIfPossible(bool is_canary_job) { |
| 969 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1030 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 970 SyncSessionJob* job_to_execute = NULL; | 1031 SyncSessionJob* job_to_execute = NULL; |
| 971 if (mode_ == CONFIGURATION_MODE && wait_interval_.get() | 1032 if (mode_ == CONFIGURATION_MODE && wait_interval_.get() |
| 972 && wait_interval_->pending_configure_job.get()) { | 1033 && wait_interval_->pending_configure_job.get()) { |
| 973 SDVLOG(2) << "Found pending configure job"; | 1034 SDVLOG(2) << "Found pending configure job"; |
| 974 job_to_execute = wait_interval_->pending_configure_job.get(); | 1035 job_to_execute = wait_interval_->pending_configure_job.get(); |
| 975 } else if (mode_ == NORMAL_MODE && pending_nudge_.get()) { | 1036 } else if (mode_ == NORMAL_MODE && pending_nudge_.get()) { |
| 976 SDVLOG(2) << "Found pending nudge job"; | 1037 SDVLOG(2) << "Found pending nudge job"; |
| 977 // Pending jobs mostly have time from the past. Reset it so this job | |
| 978 // will get executed. | |
| 979 if (pending_nudge_->scheduled_start < TimeTicks::Now()) | |
| 980 pending_nudge_->scheduled_start = TimeTicks::Now(); | |
| 981 | 1038 |
| 982 scoped_ptr<SyncSession> session(CreateSyncSession( | 1039 scoped_ptr<SyncSession> session(CreateSyncSession( |
| 983 pending_nudge_->session->source())); | 1040 pending_nudge_->session->source())); |
| 984 | 1041 |
| 985 // Also the routing info might have been changed since we cached the | 1042 // Also the routing info might have been changed since we cached the |
| 986 // pending nudge. Update it by coalescing to the latest. | 1043 // pending nudge. Update it by coalescing to the latest. |
| 987 pending_nudge_->session->Coalesce(*(session.get())); | 1044 pending_nudge_->session->Coalesce(*(session.get())); |
| 988 // The pending nudge would be cleared in the DoSyncSessionJob function. | 1045 // The pending nudge would be cleared in the DoSyncSessionJob function. |
| 989 job_to_execute = pending_nudge_.get(); | 1046 job_to_execute = pending_nudge_.get(); |
| 990 } | 1047 } |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1119 | 1176 |
| 1120 #undef SDVLOG_LOC | 1177 #undef SDVLOG_LOC |
| 1121 | 1178 |
| 1122 #undef SDVLOG | 1179 #undef SDVLOG |
| 1123 | 1180 |
| 1124 #undef SLOG | 1181 #undef SLOG |
| 1125 | 1182 |
| 1126 #undef ENUM_CASE | 1183 #undef ENUM_CASE |
| 1127 | 1184 |
| 1128 } // namespace syncer | 1185 } // namespace syncer |
| OLD | NEW |