summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/sync')
-rw-r--r--chrome/browser/sync/engine/syncer_thread.cc72
-rw-r--r--chrome/browser/sync/engine/syncer_thread.h66
-rw-r--r--chrome/browser/sync/engine/syncer_thread_unittest.cc360
3 files changed, 347 insertions, 151 deletions
diff --git a/chrome/browser/sync/engine/syncer_thread.cc b/chrome/browser/sync/engine/syncer_thread.cc
index e509a83..2ab6106 100644
--- a/chrome/browser/sync/engine/syncer_thread.cc
+++ b/chrome/browser/sync/engine/syncer_thread.cc
@@ -130,13 +130,19 @@ SyncerThread* SyncerThreadFactory::Create(
}
}
-bool SyncerThread::NudgeSyncer(int milliseconds_from_now, NudgeSource source) {
+void SyncerThread::NudgeSyncer(int milliseconds_from_now, NudgeSource source) {
AutoLock lock(lock_);
if (vault_.syncer_ == NULL) {
- return false;
+ return;
+ }
+
+ if (vault_.current_wait_interval_.had_nudge_during_backoff) {
+ // Drop nudges on the floor if we've already had one since starting this
+ // stage of exponential backoff.
+ return;
}
+
NudgeSyncImpl(milliseconds_from_now, source);
- return true;
}
SyncerThread::SyncerThread()
@@ -307,7 +313,7 @@ void SyncerThread::ThreadMainLoop() {
LOG(INFO) << "In thread main loop.";
// Use the short poll value by default.
- TimeDelta poll_seconds =
+ vault_.current_wait_interval_.poll_delta =
TimeDelta::FromSeconds(syncer_short_poll_interval_seconds_);
int user_idle_milliseconds = 0;
TimeTicks last_sync_time;
@@ -335,7 +341,8 @@ void SyncerThread::ThreadMainLoop() {
continue;
}
- const TimeTicks next_poll = last_sync_time + poll_seconds;
+ const TimeTicks next_poll = last_sync_time +
+ vault_.current_wait_interval_.poll_delta;
const TimeTicks end_wait =
!vault_.nudge_queue_.empty() &&
vault_.nudge_queue_.top().first < next_poll ?
@@ -365,28 +372,32 @@ void SyncerThread::ThreadMainLoop() {
// Handle a nudge, caused by either a notification or a local bookmark
// event. This will also update the source of the following SyncMain call.
- UpdateNudgeSource(&continue_sync_cycle, &initial_sync_for_thread);
+ bool nudged = UpdateNudgeSource(continue_sync_cycle,
+ &initial_sync_for_thread);
LOG(INFO) << "Calling Sync Main at time " << Time::Now().ToInternalValue();
SyncMain(vault_.syncer_);
last_sync_time = TimeTicks::Now();
LOG(INFO) << "Updating the next polling time after SyncMain";
- poll_seconds = TimeDelta::FromSeconds(CalculatePollingWaitTime(
- allstatus_->status(), static_cast<int>(poll_seconds.InSeconds()),
- &user_idle_milliseconds, &continue_sync_cycle));
+ vault_.current_wait_interval_ = CalculatePollingWaitTime(
+ allstatus_->status(),
+ static_cast<int>(vault_.current_wait_interval_.poll_delta.InSeconds()),
+ &user_idle_milliseconds, &continue_sync_cycle, nudged);
}
-
}
// We check how long the user's been idle and sync less often if the machine is
// not in use. The aim is to reduce server load.
// TODO(timsteele): Should use Time(Delta).
-int SyncerThread::CalculatePollingWaitTime(
+SyncerThread::WaitInterval SyncerThread::CalculatePollingWaitTime(
const AllStatus::Status& status,
int last_poll_wait, // Time in seconds.
int* user_idle_milliseconds,
- bool* continue_sync_cycle) {
+ bool* continue_sync_cycle,
+ bool was_nudged) {
+ lock_.AssertAcquired(); // We access 'vault' in here, so we need the lock.
+ WaitInterval return_interval;
bool is_continuing_sync_cyle = *continue_sync_cycle;
*continue_sync_cycle = false;
@@ -402,15 +413,28 @@ int SyncerThread::CalculatePollingWaitTime(
syncer_short_poll_interval_seconds_ :
syncer_long_poll_interval_seconds_;
int default_next_wait = syncer_polling_interval_;
- int actual_next_wait = default_next_wait;
+ return_interval.poll_delta = TimeDelta::FromSeconds(default_next_wait);
if (syncer_has_work_to_do) {
// Provide exponential backoff due to consecutive errors, else attempt to
// complete the work as soon as possible.
- if (!is_continuing_sync_cyle) {
- actual_next_wait = AllStatus::GetRecommendedDelaySeconds(0);
+ if (is_continuing_sync_cyle) {
+ return_interval.mode = WaitInterval::EXPONENTIAL_BACKOFF;
+ if (was_nudged && vault_.current_wait_interval_.mode ==
+ WaitInterval::EXPONENTIAL_BACKOFF) {
+ // We were nudged, it failed, and we were already in backoff.
+ return_interval.had_nudge_during_backoff = true;
+ // Keep exponent for exponential backoff the same in this case.
+ return_interval.poll_delta = vault_.current_wait_interval_.poll_delta;
+ } else {
+ // We weren't nudged, or we were in a NORMAL wait interval until now.
+ return_interval.poll_delta = TimeDelta::FromSeconds(
+ AllStatus::GetRecommendedDelaySeconds(last_poll_wait));
+ }
} else {
- actual_next_wait = AllStatus::GetRecommendedDelaySeconds(last_poll_wait);
+ // No consecutive error.
+ return_interval.poll_delta = TimeDelta::FromSeconds(
+ AllStatus::GetRecommendedDelaySeconds(0));
}
*continue_sync_cycle = true;
} else if (!status.notifications_enabled) {
@@ -424,15 +448,17 @@ int SyncerThread::CalculatePollingWaitTime(
if (new_idle_time < *user_idle_milliseconds) {
*user_idle_milliseconds = new_idle_time;
}
- actual_next_wait = CalculateSyncWaitTime(last_poll_wait * 1000,
- *user_idle_milliseconds) / 1000;
- DCHECK_GE(actual_next_wait, default_next_wait);
+ return_interval.poll_delta = TimeDelta::FromMilliseconds(
+ CalculateSyncWaitTime(last_poll_wait * 1000,
+ *user_idle_milliseconds));
+ DCHECK_GE(return_interval.poll_delta.InSeconds(), default_next_wait);
}
LOG(INFO) << "Sync wait: idle " << default_next_wait
- << " non-idle or backoff " << actual_next_wait << ".";
+ << " non-idle or backoff "
+ << return_interval.poll_delta.InSeconds() << ".";
- return actual_next_wait;
+ return return_interval;
}
void SyncerThread::ThreadMain() {
@@ -453,7 +479,7 @@ void SyncerThread::SyncMain(Syncer* syncer) {
LOG(INFO) << "Done looping in sync share";
}
-void SyncerThread::UpdateNudgeSource(bool* continue_sync_cycle,
+bool SyncerThread::UpdateNudgeSource(bool continue_sync_cycle,
bool* initial_sync) {
bool nudged = false;
NudgeSource nudge_source = kUnknown;
@@ -467,12 +493,12 @@ void SyncerThread::UpdateNudgeSource(bool* continue_sync_cycle,
TimeTicks::Now() >= vault_.nudge_queue_.top().first) {
if (!nudged) {
nudge_source = vault_.nudge_queue_.top().second;
- *continue_sync_cycle = false; // Reset the continuation token on nudge.
nudged = true;
}
vault_.nudge_queue_.pop();
}
SetUpdatesSource(nudged, nudge_source, initial_sync);
+ return nudged;
}
void SyncerThread::SetUpdatesSource(bool nudged, NudgeSource nudge_source,
diff --git a/chrome/browser/sync/engine/syncer_thread.h b/chrome/browser/sync/engine/syncer_thread.h
index d6fc63a..e68ac70 100644
--- a/chrome/browser/sync/engine/syncer_thread.h
+++ b/chrome/browser/sync/engine/syncer_thread.h
@@ -74,6 +74,30 @@ class SyncerThread : public base::RefCountedThreadSafe<SyncerThread> {
friend class SyncerThreadWithSyncerTest;
friend class SyncerThreadFactory;
public:
+ // Encapsulates the parameters that make up an interval on which the
+ // syncer thread is sleeping.
+ struct WaitInterval {
+ enum Mode {
+ // A wait interval whose duration has not been affected by exponential
+ // backoff. The base case for exponential backoff falls in to this case
+ // (e.g when the exponent is 1). So far, we don't need a separate case.
+ // NORMAL intervals are not nudge-rate limited.
+ NORMAL,
+ // A wait interval whose duration has been affected by exponential
+ // backoff.
+ // EXPONENTIAL_BACKOFF intervals are nudge-rate limited to 1 per interval.
+ EXPONENTIAL_BACKOFF,
+ };
+
+ Mode mode;
+ // This bool is set to true if we have observed a nudge during during this
+ // interval and mode == EXPONENTIAL_BACKOFF.
+ bool had_nudge_during_backoff;
+ base::TimeDelta poll_delta; // The wait duration until the next poll.
+
+ WaitInterval() : mode(NORMAL), had_nudge_during_backoff(false) { }
+ };
+
enum NudgeSource {
kUnknown = 0,
kNotification,
@@ -103,7 +127,7 @@ public:
// Nudges the syncer to sync with a delay specified. This API is for access
// from the SyncerThread's controller and will cause a mutex lock.
- virtual bool NudgeSyncer(int milliseconds_from_now, NudgeSource source);
+ virtual void NudgeSyncer(int milliseconds_from_now, NudgeSource source);
// Registers this thread to watch talk mediator events.
virtual void WatchTalkMediator(TalkMediator* talk_mediator);
@@ -172,6 +196,13 @@ public:
// NudgeQueue().
NudgeQueue nudge_queue_;
+ // The wait interval for to the current iteration of our main loop. This is
+ // only written to by the syncer thread, and since the only reader from a
+ // different thread (NudgeSync) is called at totally random times, we don't
+ // really need to access mutually exclusively as the data races that exist
+ // are intrinsic, but do so anyway and avoid using 'volatile'.
+ WaitInterval current_wait_interval_;
+
ProtectedFields()
: stop_syncer_thread_(false), syncer_(NULL), connected_(false) {}
} vault_;
@@ -184,12 +215,6 @@ public:
Lock lock_;
private:
- // A few members to gate the rate at which we nudge the syncer.
- enum {
- kNudgeRateLimitCount = 6,
- kNudgeRateLimitTime = 180,
- };
-
// Threshold multipler for how long before user should be considered idle.
static const int kPollBackoffThresholdMultiplier = 10;
@@ -206,25 +231,30 @@ public:
void SyncMain(Syncer* syncer);
- // Calculates the next sync wait time in seconds. last_poll_wait is the time
- // duration of the previous polling timeout which was used.
- // user_idle_milliseconds is updated by this method, and is a report of the
- // full amount of time since the last period of activity for the user. The
- // continue_sync_cycle parameter is used to determine whether or not we are
- // calculating a polling wait time that is a continuation of an sync cycle
- // which terminated while the syncer still had work to do.
- virtual int CalculatePollingWaitTime(
+ // Calculates the next sync wait time and exponential backoff state.
+ // last_poll_wait is the time duration of the previous polling timeout which
+ // was used. user_idle_milliseconds is updated by this method, and is a report
+ // of the full amount of time since the last period of activity for the user.
+ // The continue_sync_cycle parameter is used to determine whether or not we
+ // are calculating a polling wait time that is a continuation of an sync cycle
+ // which terminated while the syncer still had work to do. was_nudged is used
+ // in case of exponential backoff so we only allow one nudge per backoff
+ // interval.
+ WaitInterval CalculatePollingWaitTime(
const AllStatus::Status& status,
int last_poll_wait, // in s
int* user_idle_milliseconds,
- bool* continue_sync_cycle);
+ bool* continue_sync_cycle,
+ bool was_nudged);
+
// Helper to above function, considers effect of user idle time.
virtual int CalculateSyncWaitTime(int last_wait, int user_idle_ms);
// Sets the source value of the controlled syncer's updates_source value.
// The initial sync boolean is updated if read as a sentinel. The following
- // two methods work in concert to achieve this goal.
- void UpdateNudgeSource(bool* continue_sync_cycle,
+ // two methods work in concert to achieve this goal. Returns true if it
+ // determines a nudge actually occurred.
+ bool UpdateNudgeSource(bool continue_sync_cycle,
bool* initial_sync);
void SetUpdatesSource(bool nudged, NudgeSource nudge_source,
bool* initial_sync);
diff --git a/chrome/browser/sync/engine/syncer_thread_unittest.cc b/chrome/browser/sync/engine/syncer_thread_unittest.cc
index 846ad36..b80fa30 100644
--- a/chrome/browser/sync/engine/syncer_thread_unittest.cc
+++ b/chrome/browser/sync/engine/syncer_thread_unittest.cc
@@ -22,6 +22,7 @@ using base::TimeDelta;
namespace browser_sync {
typedef testing::Test SyncerThreadTest;
+typedef SyncerThread::WaitInterval WaitInterval;
class SyncerThreadWithSyncerTest : public testing::Test {
public:
@@ -158,6 +159,8 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
scoped_refptr<SyncerThread> syncer_thread(
SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL));
syncer_thread->DisableIdleDetection();
+ // Hold the lock to appease asserts in code.
+ AutoLock lock(syncer_thread->lock_);
// Notifications disabled should result in a polling interval of
// kDefaultShortPollInterval.
@@ -167,27 +170,33 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
bool continue_sync_cycle_param = false;
// No work and no backoff.
- ASSERT_TRUE(SyncerThread::kDefaultShortPollIntervalSeconds ==
- syncer_thread->CalculatePollingWaitTime(
- status,
- 0,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ WaitInterval interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 0,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds,
+ interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_FALSE(continue_sync_cycle_param);
// In this case the continue_sync_cycle is turned off.
continue_sync_cycle_param = true;
- ASSERT_TRUE(SyncerThread::kDefaultShortPollIntervalSeconds ==
- syncer_thread->CalculatePollingWaitTime(
- status,
- 0,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 0,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds,
+ interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_FALSE(continue_sync_cycle_param);
-
- // TODO(brg) : Find a way to test exponential backoff is inoperable.
- // Exponential backoff should be turned on when notifications are disabled
- // but this can not be tested since we can not set the last input info.
}
// Notifications enabled should result in a polling interval of
@@ -198,27 +207,33 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
bool continue_sync_cycle_param = false;
// No work and no backoff.
- ASSERT_TRUE(SyncerThread::kDefaultLongPollIntervalSeconds ==
- syncer_thread->CalculatePollingWaitTime(
- status,
- 0,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ WaitInterval interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 0,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds,
+ interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_FALSE(continue_sync_cycle_param);
// In this case the continue_sync_cycle is turned off.
continue_sync_cycle_param = true;
- ASSERT_TRUE(SyncerThread::kDefaultLongPollIntervalSeconds ==
- syncer_thread->CalculatePollingWaitTime(
- status,
- 0,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 0,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds,
+ interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_FALSE(continue_sync_cycle_param);
-
- // TODO(brg) : Find a way to test exponential backoff.
- // Exponential backoff should be turned off when notifications are enabled,
- // but this can not be tested since we can not set the last input info.
}
// There are two states which can cause a continuation, either the updates
@@ -230,40 +245,66 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
status.updates_received = 0;
bool continue_sync_cycle_param = false;
- ASSERT_TRUE(0 <= syncer_thread->CalculatePollingWaitTime(
- status,
- 0,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ WaitInterval interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 0,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_LE(0, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_TRUE(continue_sync_cycle_param);
continue_sync_cycle_param = false;
- ASSERT_TRUE(3 >= syncer_thread->CalculatePollingWaitTime(
- status,
- 0,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 0,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_GE(3, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_TRUE(continue_sync_cycle_param);
- ASSERT_TRUE(0 <= syncer_thread->CalculatePollingWaitTime(
- status,
- 0,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
- ASSERT_TRUE(2 >= syncer_thread->CalculatePollingWaitTime(
- status,
- 0,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 0,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_LE(0, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
+
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 0,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_GE(2, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_TRUE(continue_sync_cycle_param);
status.updates_received = 1;
- ASSERT_TRUE(SyncerThread::kDefaultShortPollIntervalSeconds ==
- syncer_thread->CalculatePollingWaitTime(
- status,
- 10,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 0,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds,
+ interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_FALSE(continue_sync_cycle_param);
}
@@ -272,28 +313,43 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
status.unsynced_count = 1;
bool continue_sync_cycle_param = false;
- ASSERT_TRUE(0 <= syncer_thread->CalculatePollingWaitTime(
- status,
- 0,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ WaitInterval interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 0,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_LE(0, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_TRUE(continue_sync_cycle_param);
continue_sync_cycle_param = false;
- ASSERT_TRUE(2 >= syncer_thread->CalculatePollingWaitTime(
- status,
- 0,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 0,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_GE(2, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_TRUE(continue_sync_cycle_param);
status.unsynced_count = 0;
- ASSERT_TRUE(SyncerThread::kDefaultShortPollIntervalSeconds ==
- syncer_thread->CalculatePollingWaitTime(
- status,
- 4,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 4,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds,
+ interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_FALSE(continue_sync_cycle_param);
}
@@ -305,60 +361,144 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
// Expect move from default polling interval to exponential backoff due to
// unsynced_count != 0.
- ASSERT_TRUE(0 <= syncer_thread->CalculatePollingWaitTime(
- status,
- 3600,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ WaitInterval interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 3600,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_LE(0, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_TRUE(continue_sync_cycle_param);
continue_sync_cycle_param = false;
- ASSERT_TRUE(2 >= syncer_thread->CalculatePollingWaitTime(
- status,
- 3600,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 3600,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_GE(2, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_TRUE(continue_sync_cycle_param);
// Expect exponential backoff.
- ASSERT_TRUE(2 <= syncer_thread->CalculatePollingWaitTime(
- status,
- 2,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
- ASSERT_TRUE(6 >= syncer_thread->CalculatePollingWaitTime(
- status,
- 2,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 2,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_LE(2, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
+ ASSERT_TRUE(continue_sync_cycle_param);
+
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 2,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_GE(6, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
+ ASSERT_TRUE(continue_sync_cycle_param);
+
+ syncer_thread->vault_.current_wait_interval_ = interval;
+
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ static_cast<int>(interval.poll_delta.InSeconds()),
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ true);
+
+ // Don't change poll on a failed nudge during backoff.
+ ASSERT_TRUE(syncer_thread->vault_.current_wait_interval_.poll_delta ==
+ interval.poll_delta);
+ ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
+ ASSERT_TRUE(interval.had_nudge_during_backoff);
+ ASSERT_TRUE(continue_sync_cycle_param);
+
+ // If we got a nudge and we weren't in backoff mode, we see exponential
+ // backoff.
+ syncer_thread->vault_.current_wait_interval_.mode = WaitInterval::NORMAL;
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 2,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ true);
+
+ // 5 and 3 are bounds on the backoff randomization formula given input of 2.
+ ASSERT_GE(5, interval.poll_delta.InSeconds());
+ ASSERT_LE(3, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
+ ASSERT_TRUE(continue_sync_cycle_param);
+
+ // And if another interval expires, we get a bigger backoff.
+ WaitInterval new_interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ static_cast<int>(interval.poll_delta.InSeconds()),
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ false);
+
+ ASSERT_GE(12, new_interval.poll_delta.InSeconds());
+ ASSERT_LE(5, new_interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
+ ASSERT_FALSE(new_interval.had_nudge_during_backoff);
ASSERT_TRUE(continue_sync_cycle_param);
// A nudge resets the continue_sync_cycle_param value, so our backoff
// should return to the minimum.
continue_sync_cycle_param = false;
- ASSERT_TRUE(0 <= syncer_thread->CalculatePollingWaitTime(
- status,
- 3600,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 3600,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ true);
+
+ ASSERT_LE(0, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_TRUE(continue_sync_cycle_param);
continue_sync_cycle_param = false;
- ASSERT_TRUE(2 >= syncer_thread->CalculatePollingWaitTime(
- status,
- 3600,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 3600,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ true);
+
+ ASSERT_GE(2, interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_TRUE(continue_sync_cycle_param);
// Setting unsynced_count = 0 returns us to the default polling interval.
status.unsynced_count = 0;
- ASSERT_TRUE(SyncerThread::kDefaultShortPollIntervalSeconds ==
- syncer_thread->CalculatePollingWaitTime(
- status,
- 4,
- &user_idle_milliseconds_param,
- &continue_sync_cycle_param));
+ interval = syncer_thread->CalculatePollingWaitTime(
+ status,
+ 4,
+ &user_idle_milliseconds_param,
+ &continue_sync_cycle_param,
+ true);
+
+ ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds,
+ interval.poll_delta.InSeconds());
+ ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
+ ASSERT_FALSE(interval.had_nudge_during_backoff);
ASSERT_FALSE(continue_sync_cycle_param);
}
}