Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Unified Diff: sync/engine/sync_scheduler_impl.cc

Issue 12538015: sync: Handle POLL jobs in separate a code path (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sync/engine/sync_scheduler_impl.cc
diff --git a/sync/engine/sync_scheduler_impl.cc b/sync/engine/sync_scheduler_impl.cc
index 0f55c5fa8dd99cb944adfcef61eea1ccbb272d78..9a7985cacc51bb5ce14f34f1b9267bf1c3dfa3c1 100644
--- a/sync/engine/sync_scheduler_impl.cc
+++ b/sync/engine/sync_scheduler_impl.cc
@@ -343,15 +343,13 @@ SyncSchedulerImpl::DecideWhileInWaitInterval(const SyncSessionJob& job,
JobPriority priority) {
DCHECK_EQ(MessageLoop::current(), sync_loop_);
DCHECK(wait_interval_.get());
+ DCHECK_NE(job.purpose(), SyncSessionJob::POLL);
SDVLOG(2) << "DecideWhileInWaitInterval with WaitInterval mode "
<< WaitInterval::GetModeString(wait_interval_->mode)
<< (wait_interval_->had_nudge ? " (had nudge)" : "")
<< ((priority == CANARY_PRIORITY) ? " (canary)" : "");
- if (job.purpose() == SyncSessionJob::POLL)
- return DROP;
-
// If we save a job while in a WaitInterval, there is a well-defined moment
// in time in the future when it makes sense for that SAVE-worthy job to try
// running again -- the end of the WaitInterval.
@@ -383,6 +381,10 @@ SyncSchedulerImpl::JobProcessDecision SyncSchedulerImpl::DecideOnJob(
JobPriority priority) {
DCHECK_EQ(MessageLoop::current(), sync_loop_);
+ // POLL jobs do not call this function.
+ DCHECK(job.purpose() == SyncSessionJob::NUDGE ||
+ job.purpose() == SyncSessionJob::CONFIGURATION);
+
// See if our type is throttled.
ModelTypeSet throttled_types =
session_context_->throttled_data_type_tracker()->GetThrottledTypes();
@@ -412,10 +414,8 @@ SyncSchedulerImpl::JobProcessDecision SyncSchedulerImpl::DecideOnJob(
if (mode_ == CONFIGURATION_MODE) {
if (job.purpose() == SyncSessionJob::NUDGE)
return SAVE; // Running requires a mode switch.
- else if (job.purpose() == SyncSessionJob::CONFIGURATION)
+ else // job.purpose() == SyncSessionJob::CONFIGURATION
return CONTINUE;
- else
- return DROP;
}
// We are in normal mode.
@@ -683,6 +683,7 @@ void SyncSchedulerImpl::ScheduleSyncSessionJob(
const tracked_objects::Location& loc,
scoped_ptr<SyncSessionJob> job) {
DCHECK_EQ(MessageLoop::current(), sync_loop_);
+ DCHECK_EQ(job->purpose(), SyncSessionJob::NUDGE);
if (no_scheduling_allowed_) {
NOTREACHED() << "Illegal to schedule job while session in progress.";
return;
@@ -696,14 +697,10 @@ void SyncSchedulerImpl::ScheduleSyncSessionJob(
<< SyncSessionJob::GetPurposeString(job->purpose())
<< " job and " << delay.InMilliseconds() << " ms delay";
- DCHECK(job->purpose() == SyncSessionJob::NUDGE ||
- job->purpose() == SyncSessionJob::POLL);
- if (job->purpose() == SyncSessionJob::NUDGE) {
- SDVLOG_LOC(loc, 2) << "Resetting pending_nudge to ";
- DCHECK(!pending_nudge_ || pending_nudge_->session() ==
- job->session());
- pending_nudge_ = job.get();
- }
+ SDVLOG_LOC(loc, 2) << "Resetting pending_nudge to ";
+ DCHECK(!pending_nudge_ || pending_nudge_->session() ==
+ job->session());
+ pending_nudge_ = job.get();
PostDelayedTask(loc, "DoSyncSessionJob",
base::Bind(base::IgnoreResult(&SyncSchedulerImpl::DoSyncSessionJob),
@@ -756,7 +753,75 @@ bool SyncSchedulerImpl::DoSyncSessionJob(scoped_ptr<SyncSessionJob> job,
job->end_step());
SDVLOG(2) << "Done SyncShare, returned: " << premature_exit;
- return FinishSyncSessionJob(job.Pass(), premature_exit);
+ bool success = FinishSyncSessionJob(job.get(), premature_exit);
+
+ if (IsSyncingCurrentlySilenced()) {
+ SDVLOG(2) << "We are currently throttled; scheduling Unthrottle.";
+ // If we're here, it's because |job| was silenced until a server specified
+ // time. (Note, it had to be |job|, because DecideOnJob would not permit
+ // any job through while in WaitInterval::THROTTLED).
+ scoped_ptr<SyncSessionJob> clone = job->Clone();
+ if (clone->purpose() == SyncSessionJob::NUDGE)
+ pending_nudge_ = clone.get();
+ else if (clone->purpose() == SyncSessionJob::CONFIGURATION)
+ wait_interval_->pending_configure_job = clone.get();
+ else
+ NOTREACHED();
+
+ RestartWaiting(clone.Pass());
+ return success;
+ }
+
+ if (!success)
+ ScheduleNextSync(job.Pass());
+
+ return success;
+}
+
+bool SyncSchedulerImpl::DecideOnPollJob() {
+ if (wait_interval_.get()) {
+ SDVLOG(2) << "Dropping POLL job in wait interval.";
+ return false;
+ }
+
+ if (mode_ == CONFIGURATION_MODE) {
+ SDVLOG(2) << "Dropping POLL job in configuration mode.";
+ return false;
+ }
+
+ if (session_context_->connection_manager()->HasInvalidAuthToken()) {
tim (not reviewing) 2013/03/19 21:50:02 Can you add a TODO to track moving this to a DoCom
rlarocque 2013/03/19 22:46:42 Done.
+ SDVLOG(2) << "Dropping POLL job because auth token is invalid.";
+ return false;
+ }
+
+ return true;
+}
+
+void SyncSchedulerImpl::DoPollSyncSessionJob(scoped_ptr<SyncSessionJob> job) {
+ DCHECK_EQ(job->purpose(), SyncSessionJob::POLL);
+
+ base::AutoReset<bool> protector(&no_scheduling_allowed_, true);
+
+ if (!DecideOnPollJob())
tim (not reviewing) 2013/03/19 21:50:02 Is your plant o make DecideOnJob() return a bool a
rlarocque 2013/03/19 22:46:42 You're right. This CL is probably the most approp
rlarocque 2013/03/19 22:46:42 You're right that the name should change. I think
+ return;
+
+ SDVLOG(2) << "Calling SyncShare with "
+ << SyncSessionJob::GetPurposeString(job->purpose()) << " job";
+ bool premature_exit = !syncer_->SyncShare(job->mutable_session(),
+ job->start_step(),
+ job->end_step());
+ SDVLOG(2) << "Done SyncShare, returned: " << premature_exit;
+
+ FinishSyncSessionJob(job.get(), premature_exit);
+
+ if (IsSyncingCurrentlySilenced()) {
+ // This will start the countdown to unthrottle. Other kinds of jobs would
+ // schedule themselves as the post-unthrottle canary. A poll job is not
+ // that urgent, so it does not get to be the canary. We still need to start
+ // the timer regardless. Otherwise there could be no one to clear the
+ // WaitInterval when the throttling expires.
+ RestartWaiting(scoped_ptr<SyncSessionJob>());
+ }
}
void SyncSchedulerImpl::UpdateNudgeTimeRecords(const SyncSourceInfo& info) {
@@ -784,7 +849,7 @@ void SyncSchedulerImpl::UpdateNudgeTimeRecords(const SyncSourceInfo& info) {
}
}
-bool SyncSchedulerImpl::FinishSyncSessionJob(scoped_ptr<SyncSessionJob> job,
+bool SyncSchedulerImpl::FinishSyncSessionJob(SyncSessionJob* job,
bool exited_prematurely) {
DCHECK_EQ(MessageLoop::current(), sync_loop_);
@@ -796,15 +861,8 @@ bool SyncSchedulerImpl::FinishSyncSessionJob(scoped_ptr<SyncSessionJob> job,
}
SDVLOG(2) << "Updating the next polling time after SyncMain";
- ScheduleNextSync(job.Pass(), succeeded);
- return succeeded;
-}
-
-void SyncSchedulerImpl::ScheduleNextSync(
- scoped_ptr<SyncSessionJob> finished_job, bool succeeded) {
- DCHECK_EQ(MessageLoop::current(), sync_loop_);
- AdjustPolling(finished_job.get());
+ AdjustPolling(job);
if (succeeded) {
// No job currently supported by the scheduler could succeed without
@@ -813,29 +871,16 @@ void SyncSchedulerImpl::ScheduleNextSync(
wait_interval_.reset();
NotifyRetryTime(base::Time());
SDVLOG(2) << "Job succeeded so not scheduling more jobs";
- return;
}
- if (IsSyncingCurrentlySilenced()) {
- SDVLOG(2) << "We are currently throttled; scheduling Unthrottle.";
- // If we're here, it's because |job| was silenced until a server specified
- // time. (Note, it had to be |job|, because DecideOnJob would not permit
- // any job through while in WaitInterval::THROTTLED).
- scoped_ptr<SyncSessionJob> clone = finished_job->Clone();
- if (clone->purpose() == SyncSessionJob::NUDGE)
- pending_nudge_ = clone.get();
- else if (clone->purpose() == SyncSessionJob::CONFIGURATION)
- wait_interval_->pending_configure_job = clone.get();
- else
- clone.reset(); // Unthrottling is enough, no need to force a canary.
-
- RestartWaiting(clone.Pass());
- return;
- }
+ return succeeded;
+}
- if (finished_job->purpose() == SyncSessionJob::POLL) {
- return; // We don't retry POLL jobs.
- }
+void SyncSchedulerImpl::ScheduleNextSync(
+ scoped_ptr<SyncSessionJob> finished_job) {
+ DCHECK_EQ(MessageLoop::current(), sync_loop_);
+ DCHECK(finished_job->purpose() == SyncSessionJob::CONFIGURATION
+ || finished_job->purpose() == SyncSessionJob::NUDGE);
// TODO(rlarocque): There's no reason why we should blindly backoff and retry
// if we don't succeed. Some types of errors are not likely to disappear on
@@ -980,7 +1025,7 @@ void SyncSchedulerImpl::DoCanaryJob(scoped_ptr<SyncSessionJob> to_be_canary) {
pending_nudge_->session() != to_be_canary->session()) {
// |job| is abandoned.
SDVLOG(2) << "Dropping a nudge in "
- << "DoSyncSessionJob because another nudge was scheduled";
+ << "DoCanaryJob because another nudge was scheduled";
return;
}
DCHECK_EQ(pending_nudge_->session(), to_be_canary->session());
@@ -1035,7 +1080,18 @@ void SyncSchedulerImpl::PollTimerCallback() {
TimeTicks::Now(),
s.Pass(),
ConfigurationParams()));
- ScheduleSyncSessionJob(FROM_HERE, job.Pass());
+ if (no_scheduling_allowed_) {
+ // The no_scheduling_allowed_ flag is set by a function-scoped AutoReset in
+ // functions that are called only on the sync thread. This function is also
+ // called only on the sync thread, and only when it is posted by an expiring
+ // timer. If we find that no_scheduling_allowed_ is set here, then
+ // something is very wrong. Maybe someone mistakenly called us directly, or
+ // mishandled the book-keeping for no_scheduling_allowed_.
+ NOTREACHED() << "Illegal to schedule job while session in progress.";
+ return;
+ }
+
+ DoPollSyncSessionJob(job.Pass());
}
void SyncSchedulerImpl::Unthrottle(scoped_ptr<SyncSessionJob> to_be_canary) {

Powered by Google App Engine
This is Rietveld 408576698