summaryrefslogtreecommitdiffstats
path: root/sync
diff options
context:
space:
mode:
authorzea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-22 21:41:11 +0000
committerzea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-22 21:45:07 +0000
commit9b8535f1150f0b8dc6920ba47c8436510b302693 (patch)
tree8b5c09e3f11a27269a1b8638e4daa52da9796042 /sync
parent272098237b925537dccc45bab30006a27831a3ed (diff)
downloadchromium_src-9b8535f1150f0b8dc6920ba47c8436510b302693.zip
chromium_src-9b8535f1150f0b8dc6920ba47c8436510b302693.tar.gz
chromium_src-9b8535f1150f0b8dc6920ba47c8436510b302693.tar.bz2
[Sync] Add support for server controlled nudge delays
Server nudge delays override the local ones, but must be longer than the default nudge delay. If set to 0, will reset the nudge to the default. To accomplish this the delay logic was refactored and moved into the sync scheduler, which is now aware of all delays for all types and sync cycles. BUG=401600 Review URL: https://codereview.chromium.org/488843002 Cr-Commit-Position: refs/heads/master@{#291512} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@291512 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync')
-rw-r--r--sync/engine/sync_scheduler.h5
-rw-r--r--sync/engine/sync_scheduler_impl.cc69
-rw-r--r--sync/engine/sync_scheduler_impl.h14
-rw-r--r--sync/engine/sync_scheduler_unittest.cc150
-rw-r--r--sync/engine/syncer_proto_util.cc23
-rw-r--r--sync/engine/syncer_unittest.cc77
-rw-r--r--sync/internal_api/sync_manager_impl.cc109
-rw-r--r--sync/internal_api/sync_manager_impl.h3
-rw-r--r--sync/internal_api/sync_manager_impl_unittest.cc17
-rw-r--r--sync/protocol/client_commands.proto16
-rw-r--r--sync/sessions/data_type_tracker.cc7
-rw-r--r--sync/sessions/data_type_tracker.h10
-rw-r--r--sync/sessions/nudge_tracker.cc92
-rw-r--r--sync/sessions/nudge_tracker.h25
-rw-r--r--sync/sessions/nudge_tracker_unittest.cc79
-rw-r--r--sync/sessions/sync_session.h7
-rw-r--r--sync/sessions/test_util.cc4
-rw-r--r--sync/test/engine/fake_sync_scheduler.cc15
-rw-r--r--sync/test/engine/fake_sync_scheduler.h8
19 files changed, 389 insertions, 341 deletions
diff --git a/sync/engine/sync_scheduler.h b/sync/engine/sync_scheduler.h
index e490f94..e91ce61 100644
--- a/sync/engine/sync_scheduler.h
+++ b/sync/engine/sync_scheduler.h
@@ -96,7 +96,6 @@ class SYNC_EXPORT_PRIVATE SyncScheduler
// The LocalNudge indicates that we've made a local change, and that the
// syncer should plan to commit this to the server some time soon.
virtual void ScheduleLocalNudge(
- const base::TimeDelta& desired_delay,
ModelTypeSet types,
const tracked_objects::Location& nudge_location) = 0;
@@ -105,7 +104,6 @@ class SYNC_EXPORT_PRIVATE SyncScheduler
// uses is to fetch the latest tab sync data when it's relevant to the UI on
// platforms where tab sync is not registered for invalidations.
virtual void ScheduleLocalRefreshRequest(
- const base::TimeDelta& desired_delay,
ModelTypeSet types,
const tracked_objects::Location& nudge_location) = 0;
@@ -114,7 +112,6 @@ class SYNC_EXPORT_PRIVATE SyncScheduler
// careful to pass along the "hints" delivered with those invalidations) in
// order to fetch the update.
virtual void ScheduleInvalidationNudge(
- const base::TimeDelta& desired_delay,
syncer::ModelType type,
scoped_ptr<InvalidationInterface> invalidation,
const tracked_objects::Location& nudge_location) = 0;
@@ -130,8 +127,6 @@ class SYNC_EXPORT_PRIVATE SyncScheduler
// Change status of notifications in the SyncSessionContext.
virtual void SetNotificationsEnabled(bool notifications_enabled) = 0;
- virtual base::TimeDelta GetSessionsCommitDelay() const = 0;
-
// Called when credentials are updated by the user.
virtual void OnCredentialsUpdated() = 0;
diff --git a/sync/engine/sync_scheduler_impl.cc b/sync/engine/sync_scheduler_impl.cc
index 7b07815..22dc5e0 100644
--- a/sync/engine/sync_scheduler_impl.cc
+++ b/sync/engine/sync_scheduler_impl.cc
@@ -32,6 +32,20 @@ using sync_pb::GetUpdatesCallerInfo;
namespace {
+bool IsConfigRelatedUpdateSourceValue(
+ GetUpdatesCallerInfo::GetUpdatesSource source) {
+ switch (source) {
+ case GetUpdatesCallerInfo::RECONFIGURATION:
+ case GetUpdatesCallerInfo::MIGRATION:
+ case GetUpdatesCallerInfo::NEW_CLIENT:
+ case GetUpdatesCallerInfo::NEWLY_SUPPORTED_DATATYPE:
+ case GetUpdatesCallerInfo::PROGRAMMATIC:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool ShouldRequestEarlyExit(const SyncProtocolError& error) {
switch (error.error_type) {
case SYNC_SUCCESS:
@@ -65,6 +79,7 @@ bool IsActionableError(
const SyncProtocolError& error) {
return (error.action != UNKNOWN_ACTION);
}
+
} // namespace
ConfigurationParams::ConfigurationParams()
@@ -132,26 +147,6 @@ GetUpdatesCallerInfo::GetUpdatesSource GetUpdatesFromNudgeSource(
#define SDVLOG_LOC(from_here, verbose_level) \
DVLOG_LOC(from_here, verbose_level) << name_ << ": "
-namespace {
-
-const int kDefaultSessionsCommitDelaySeconds = 10;
-
-bool IsConfigRelatedUpdateSourceValue(
- GetUpdatesCallerInfo::GetUpdatesSource source) {
- switch (source) {
- case GetUpdatesCallerInfo::RECONFIGURATION:
- case GetUpdatesCallerInfo::MIGRATION:
- case GetUpdatesCallerInfo::NEW_CLIENT:
- case GetUpdatesCallerInfo::NEWLY_SUPPORTED_DATATYPE:
- case GetUpdatesCallerInfo::PROGRAMMATIC:
- return true;
- default:
- return false;
- }
-}
-
-} // namespace
-
SyncSchedulerImpl::SyncSchedulerImpl(const std::string& name,
BackoffDelayProvider* delay_provider,
sessions::SyncSessionContext* context,
@@ -162,8 +157,6 @@ SyncSchedulerImpl::SyncSchedulerImpl(const std::string& name,
TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds)),
syncer_long_poll_interval_seconds_(
TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)),
- sessions_commit_delay_(
- TimeDelta::FromSeconds(kDefaultSessionsCommitDelaySeconds)),
mode_(NORMAL_MODE),
delay_provider_(delay_provider),
syncer_(syncer),
@@ -357,7 +350,6 @@ bool SyncSchedulerImpl::CanRunNudgeJobNow(JobPriority priority) {
}
void SyncSchedulerImpl::ScheduleLocalNudge(
- const TimeDelta& desired_delay,
ModelTypeSet types,
const tracked_objects::Location& nudge_location) {
DCHECK(CalledOnValidThread());
@@ -367,12 +359,11 @@ void SyncSchedulerImpl::ScheduleLocalNudge(
<< "Scheduling sync because of local change to "
<< ModelTypeSetToString(types);
UpdateNudgeTimeRecords(types);
- nudge_tracker_.RecordLocalChange(types);
- ScheduleNudgeImpl(desired_delay, nudge_location);
+ base::TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(types);
+ ScheduleNudgeImpl(nudge_delay, nudge_location);
}
void SyncSchedulerImpl::ScheduleLocalRefreshRequest(
- const TimeDelta& desired_delay,
ModelTypeSet types,
const tracked_objects::Location& nudge_location) {
DCHECK(CalledOnValidThread());
@@ -381,12 +372,11 @@ void SyncSchedulerImpl::ScheduleLocalRefreshRequest(
SDVLOG_LOC(nudge_location, 2)
<< "Scheduling sync because of local refresh request for "
<< ModelTypeSetToString(types);
- nudge_tracker_.RecordLocalRefreshRequest(types);
- ScheduleNudgeImpl(desired_delay, nudge_location);
+ base::TimeDelta nudge_delay = nudge_tracker_.RecordLocalRefreshRequest(types);
+ ScheduleNudgeImpl(nudge_delay, nudge_location);
}
void SyncSchedulerImpl::ScheduleInvalidationNudge(
- const TimeDelta& desired_delay,
syncer::ModelType model_type,
scoped_ptr<InvalidationInterface> invalidation,
const tracked_objects::Location& nudge_location) {
@@ -395,8 +385,9 @@ void SyncSchedulerImpl::ScheduleInvalidationNudge(
SDVLOG_LOC(nudge_location, 2)
<< "Scheduling sync because we received invalidation for "
<< ModelTypeToString(model_type);
- nudge_tracker_.RecordRemoteInvalidation(model_type, invalidation.Pass());
- ScheduleNudgeImpl(desired_delay, nudge_location);
+ base::TimeDelta nudge_delay =
+ nudge_tracker_.RecordRemoteInvalidation(model_type, invalidation.Pass());
+ ScheduleNudgeImpl(nudge_delay, nudge_location);
}
void SyncSchedulerImpl::ScheduleInitialSyncNudge(syncer::ModelType model_type) {
@@ -462,6 +453,11 @@ const char* SyncSchedulerImpl::GetModeString(SyncScheduler::Mode mode) {
return "";
}
+void SyncSchedulerImpl::SetDefaultNudgeDelay(base::TimeDelta delay_ms) {
+ DCHECK(CalledOnValidThread());
+ nudge_tracker_.SetDefaultNudgeDelay(delay_ms);
+}
+
void SyncSchedulerImpl::DoNudgeSyncSessionJob(JobPriority priority) {
DCHECK(CalledOnValidThread());
DCHECK(CanRunNudgeJobNow(priority));
@@ -863,10 +859,10 @@ void SyncSchedulerImpl::OnReceivedLongPollIntervalUpdate(
syncer_long_poll_interval_seconds_ = new_interval;
}
-void SyncSchedulerImpl::OnReceivedSessionsCommitDelay(
- const base::TimeDelta& new_delay) {
+void SyncSchedulerImpl::OnReceivedCustomNudgeDelays(
+ const std::map<ModelType, base::TimeDelta>& nudge_delays) {
DCHECK(CalledOnValidThread());
- sessions_commit_delay_ = new_delay;
+ nudge_tracker_.OnReceivedCustomNudgeDelays(nudge_delays);
}
void SyncSchedulerImpl::OnReceivedClientInvalidationHintBufferSize(int size) {
@@ -912,11 +908,6 @@ void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) {
nudge_tracker_.OnInvalidationsDisabled();
}
-base::TimeDelta SyncSchedulerImpl::GetSessionsCommitDelay() const {
- DCHECK(CalledOnValidThread());
- return sessions_commit_delay_;
-}
-
#undef SDVLOG_LOC
#undef SDVLOG
diff --git a/sync/engine/sync_scheduler_impl.h b/sync/engine/sync_scheduler_impl.h
index 7cb295b..0e5a27a 100644
--- a/sync/engine/sync_scheduler_impl.h
+++ b/sync/engine/sync_scheduler_impl.h
@@ -56,23 +56,18 @@ class SYNC_EXPORT_PRIVATE SyncSchedulerImpl
const ConfigurationParams& params) OVERRIDE;
virtual void Stop() OVERRIDE;
virtual void ScheduleLocalNudge(
- const base::TimeDelta& desired_delay,
ModelTypeSet types,
const tracked_objects::Location& nudge_location) OVERRIDE;
virtual void ScheduleLocalRefreshRequest(
- const base::TimeDelta& desired_delay,
ModelTypeSet types,
const tracked_objects::Location& nudge_location) OVERRIDE;
virtual void ScheduleInvalidationNudge(
- const base::TimeDelta& desired_delay,
syncer::ModelType type,
scoped_ptr<InvalidationInterface> invalidation,
const tracked_objects::Location& nudge_location) OVERRIDE;
virtual void ScheduleInitialSyncNudge(syncer::ModelType model_type) OVERRIDE;
virtual void SetNotificationsEnabled(bool notifications_enabled) OVERRIDE;
- virtual base::TimeDelta GetSessionsCommitDelay() const OVERRIDE;
-
virtual void OnCredentialsUpdated() OVERRIDE;
virtual void OnConnectionStatusChange() OVERRIDE;
@@ -86,8 +81,8 @@ class SYNC_EXPORT_PRIVATE SyncSchedulerImpl
const base::TimeDelta& new_interval) OVERRIDE;
virtual void OnReceivedLongPollIntervalUpdate(
const base::TimeDelta& new_interval) OVERRIDE;
- virtual void OnReceivedSessionsCommitDelay(
- const base::TimeDelta& new_delay) OVERRIDE;
+ virtual void OnReceivedCustomNudgeDelays(
+ const std::map<ModelType, base::TimeDelta>& nudge_delays) OVERRIDE;
virtual void OnReceivedClientInvalidationHintBufferSize(int size) OVERRIDE;
virtual void OnSyncProtocolError(
const SyncProtocolError& sync_protocol_error) OVERRIDE;
@@ -150,6 +145,8 @@ class SYNC_EXPORT_PRIVATE SyncSchedulerImpl
static const char* GetModeString(Mode mode);
+ void SetDefaultNudgeDelay(base::TimeDelta delay_ms);
+
// Invoke the syncer to perform a nudge job.
void DoNudgeSyncSessionJob(JobPriority priority);
@@ -251,9 +248,6 @@ class SYNC_EXPORT_PRIVATE SyncSchedulerImpl
base::TimeDelta syncer_short_poll_interval_seconds_;
base::TimeDelta syncer_long_poll_interval_seconds_;
- // Server-tweakable sessions commit delay.
- base::TimeDelta sessions_commit_delay_;
-
// Periodic timer for polling. See AdjustPolling.
base::RepeatingTimer<SyncSchedulerImpl> poll_timer_;
diff --git a/sync/engine/sync_scheduler_unittest.cc b/sync/engine/sync_scheduler_unittest.cc
index 268fae2..a436722 100644
--- a/sync/engine/sync_scheduler_unittest.cc
+++ b/sync/engine/sync_scheduler_unittest.cc
@@ -126,8 +126,8 @@ class SyncSchedulerTest : public testing::Test {
delay_ = NULL;
extensions_activity_ = new ExtensionsActivity();
- routing_info_[BOOKMARKS] = GROUP_UI;
- routing_info_[AUTOFILL] = GROUP_DB;
+ routing_info_[THEMES] = GROUP_UI;
+ routing_info_[TYPED_URLS] = GROUP_DB;
routing_info_[THEMES] = GROUP_UI;
routing_info_[NIGORI] = GROUP_PASSIVE;
@@ -159,6 +159,7 @@ class SyncSchedulerTest : public testing::Test {
BackoffDelayProvider::FromDefaults(),
context(),
syncer_));
+ scheduler_->SetDefaultNudgeDelay(default_delay());
}
SyncSchedulerImpl* scheduler() { return scheduler_.get(); }
@@ -166,7 +167,7 @@ class SyncSchedulerTest : public testing::Test {
MockSyncer* syncer() { return syncer_; }
MockDelayProvider* delay() { return delay_; }
MockConnectionManager* connection() { return connection_.get(); }
- TimeDelta zero() { return TimeDelta::FromSeconds(0); }
+ TimeDelta default_delay() { return TimeDelta::FromSeconds(0); }
TimeDelta timeout() {
return TestTimeouts::action_timeout();
}
@@ -206,10 +207,10 @@ class SyncSchedulerTest : public testing::Test {
}
bool RunAndGetBackoff() {
- ModelTypeSet nudge_types(BOOKMARKS);
+ ModelTypeSet nudge_types(THEMES);
StartSyncScheduler(SyncScheduler::NORMAL_MODE);
- scheduler()->ScheduleLocalNudge(zero(), nudge_types, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE);
RunLoop();
return scheduler()->IsBackingOff();
@@ -298,7 +299,7 @@ ACTION(QuitLoopNowAction) {
// Test nudge scheduling.
TEST_F(SyncSchedulerTest, Nudge) {
SyncShareTimes times;
- ModelTypeSet model_types(BOOKMARKS);
+ ModelTypeSet model_types(THEMES);
EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
@@ -307,19 +308,19 @@ TEST_F(SyncSchedulerTest, Nudge) {
StartSyncScheduler(SyncScheduler::NORMAL_MODE);
- scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(model_types, FROM_HERE);
RunLoop();
Mock::VerifyAndClearExpectations(syncer());
// Make sure a second, later, nudge is unaffected by first (no coalescing).
SyncShareTimes times2;
- model_types.Remove(BOOKMARKS);
- model_types.Put(AUTOFILL);
+ model_types.Remove(THEMES);
+ model_types.Put(TYPED_URLS);
EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
RecordSyncShare(&times2)));
- scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(model_types, FROM_HERE);
RunLoop();
}
@@ -327,7 +328,7 @@ TEST_F(SyncSchedulerTest, Nudge) {
// errors.
TEST_F(SyncSchedulerTest, Config) {
SyncShareTimes times;
- const ModelTypeSet model_types(BOOKMARKS);
+ const ModelTypeSet model_types(THEMES);
EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
@@ -355,7 +356,7 @@ TEST_F(SyncSchedulerTest, ConfigWithBackingOff) {
EXPECT_CALL(*delay(), GetDelay(_))
.WillRepeatedly(Return(TimeDelta::FromMilliseconds(20)));
SyncShareTimes times;
- const ModelTypeSet model_types(BOOKMARKS);
+ const ModelTypeSet model_types(THEMES);
StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
@@ -401,7 +402,7 @@ TEST_F(SyncSchedulerTest, ConfigWithStop) {
EXPECT_CALL(*delay(), GetDelay(_))
.WillRepeatedly(Return(TimeDelta::FromMilliseconds(20)));
SyncShareTimes times;
- const ModelTypeSet model_types(BOOKMARKS);
+ const ModelTypeSet model_types(THEMES);
StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
@@ -429,7 +430,7 @@ TEST_F(SyncSchedulerTest, ConfigWithStop) {
// Issue a nudge when the config has failed. Make sure both the config and
// nudge are executed.
TEST_F(SyncSchedulerTest, NudgeWithConfigWithBackingOff) {
- const ModelTypeSet model_types(BOOKMARKS);
+ const ModelTypeSet model_types(THEMES);
UseMockDelayProvider();
EXPECT_CALL(*delay(), GetDelay(_))
.WillRepeatedly(Return(TimeDelta::FromMilliseconds(50)));
@@ -459,7 +460,7 @@ TEST_F(SyncSchedulerTest, NudgeWithConfigWithBackingOff) {
EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed),
RecordSyncShare(&times)));
- scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(model_types, FROM_HERE);
RunLoop();
// Note that we're not RunLoop()ing for the NUDGE we just scheduled, but
// for the first retry attempt from the config job (after
@@ -489,11 +490,10 @@ TEST_F(SyncSchedulerTest, NudgeCoalescing) {
EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
RecordSyncShare(&times)));
- const ModelTypeSet types1(BOOKMARKS), types2(AUTOFILL), types3(THEMES);
- TimeDelta delay = zero();
- TimeTicks optimal_time = TimeTicks::Now() + delay;
- scheduler()->ScheduleLocalNudge(delay, types1, FROM_HERE);
- scheduler()->ScheduleLocalNudge(zero(), types2, FROM_HERE);
+ const ModelTypeSet types1(THEMES), types2(TYPED_URLS), types3(THEMES);
+ TimeTicks optimal_time = TimeTicks::Now() + default_delay();
+ scheduler()->ScheduleLocalNudge(types1, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(types2, FROM_HERE);
RunLoop();
ASSERT_EQ(1U, times.size());
@@ -505,7 +505,7 @@ TEST_F(SyncSchedulerTest, NudgeCoalescing) {
EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
RecordSyncShare(&times2)));
- scheduler()->ScheduleLocalNudge(zero(), types3, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(types3, FROM_HERE);
RunLoop();
}
@@ -517,13 +517,16 @@ TEST_F(SyncSchedulerTest, NudgeCoalescingWithDifferentTimings) {
EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
RecordSyncShare(&times)));
- ModelTypeSet types1(BOOKMARKS), types2(AUTOFILL), types3;
+ ModelTypeSet types1(THEMES), types2(TYPED_URLS), types3;
// Create a huge time delay.
TimeDelta delay = TimeDelta::FromDays(1);
- scheduler()->ScheduleLocalNudge(delay, types1, FROM_HERE);
- scheduler()->ScheduleLocalNudge(zero(), types2, FROM_HERE);
+ std::map<ModelType, TimeDelta> delay_map;
+ delay_map[types1.First().Get()] = delay;
+ scheduler()->OnReceivedCustomNudgeDelays(delay_map);
+ scheduler()->ScheduleLocalNudge(types1, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(types2, FROM_HERE);
TimeTicks min_time = TimeTicks::Now();
TimeTicks max_time = TimeTicks::Now() + delay;
@@ -547,7 +550,7 @@ TEST_F(SyncSchedulerTest, NudgeWithStates) {
RecordSyncShare(&times1)))
.RetiresOnSaturation();
scheduler()->ScheduleInvalidationNudge(
- zero(), BOOKMARKS, BuildInvalidation(10, "test"), FROM_HERE);
+ THEMES, BuildInvalidation(10, "test"), FROM_HERE);
RunLoop();
Mock::VerifyAndClearExpectations(syncer());
@@ -558,7 +561,7 @@ TEST_F(SyncSchedulerTest, NudgeWithStates) {
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
RecordSyncShare(&times2)));
scheduler()->ScheduleInvalidationNudge(
- zero(), AUTOFILL, BuildInvalidation(10, "test2"), FROM_HERE);
+ TYPED_URLS, BuildInvalidation(10, "test2"), FROM_HERE);
RunLoop();
}
@@ -631,37 +634,9 @@ TEST_F(SyncSchedulerTest, PollIntervalUpdate) {
AnalyzePollRun(times, kMinNumSamples, optimal_start, poll2);
}
-// Test that the sessions commit delay is updated when needed.
-TEST_F(SyncSchedulerTest, SessionsCommitDelay) {
- SyncShareTimes times;
- TimeDelta delay1(TimeDelta::FromMilliseconds(120));
- TimeDelta delay2(TimeDelta::FromMilliseconds(30));
- scheduler()->OnReceivedSessionsCommitDelay(delay1);
-
- EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
- .WillOnce(
- DoAll(
- WithArgs<0,1,2>(
- sessions::test_util::SimulateSessionsCommitDelayUpdate(
- delay2)),
- Invoke(sessions::test_util::SimulateNormalSuccess),
- QuitLoopNowAction()));
-
- EXPECT_EQ(delay1, scheduler()->GetSessionsCommitDelay());
- StartSyncScheduler(SyncScheduler::NORMAL_MODE);
-
- EXPECT_EQ(delay1, scheduler()->GetSessionsCommitDelay());
- const ModelTypeSet model_types(BOOKMARKS);
- scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE);
- RunLoop();
-
- EXPECT_EQ(delay2, scheduler()->GetSessionsCommitDelay());
- StopSyncScheduler();
-}
-
// Test that no syncing occurs when throttled.
TEST_F(SyncSchedulerTest, ThrottlingDoesThrottle) {
- const ModelTypeSet types(BOOKMARKS);
+ const ModelTypeSet types(THEMES);
TimeDelta poll(TimeDelta::FromMilliseconds(20));
TimeDelta throttle(TimeDelta::FromMinutes(10));
scheduler()->OnReceivedLongPollIntervalUpdate(poll);
@@ -674,8 +649,7 @@ TEST_F(SyncSchedulerTest, ThrottlingDoesThrottle) {
StartSyncScheduler(SyncScheduler::NORMAL_MODE);
- scheduler()->ScheduleLocalNudge(
- TimeDelta::FromMicroseconds(1), types, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(types, FROM_HERE);
PumpLoop();
StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
@@ -738,9 +712,9 @@ TEST_F(SyncSchedulerTest, ThrottlingExpiresFromNudge) {
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
QuitLoopNowAction()));
- const ModelTypeSet types(BOOKMARKS);
+ const ModelTypeSet types(THEMES);
StartSyncScheduler(SyncScheduler::NORMAL_MODE);
- scheduler()->ScheduleLocalNudge(zero(), types, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(types, FROM_HERE);
PumpLoop(); // To get PerformDelayedNudge called.
PumpLoop(); // To get TrySyncSessionJob called
@@ -767,7 +741,7 @@ TEST_F(SyncSchedulerTest, ThrottlingExpiresFromConfigure) {
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
QuitLoopNowAction()));
- const ModelTypeSet types(BOOKMARKS);
+ const ModelTypeSet types(THEMES);
StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
CallbackCounter ready_counter;
@@ -793,13 +767,13 @@ TEST_F(SyncSchedulerTest, ThrottlingExpiresFromConfigure) {
TEST_F(SyncSchedulerTest, TypeThrottlingBlocksNudge) {
UseMockDelayProvider();
EXPECT_CALL(*delay(), GetDelay(_))
- .WillRepeatedly(Return(zero()));
+ .WillRepeatedly(Return(default_delay()));
TimeDelta poll(TimeDelta::FromDays(1));
TimeDelta throttle1(TimeDelta::FromSeconds(60));
scheduler()->OnReceivedLongPollIntervalUpdate(poll);
- const ModelTypeSet types(BOOKMARKS);
+ const ModelTypeSet types(THEMES);
::testing::InSequence seq;
EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
@@ -810,13 +784,13 @@ TEST_F(SyncSchedulerTest, TypeThrottlingBlocksNudge) {
.RetiresOnSaturation();
StartSyncScheduler(SyncScheduler::NORMAL_MODE);
- scheduler()->ScheduleLocalNudge(zero(), types, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(types, FROM_HERE);
PumpLoop(); // To get PerformDelayedNudge called.
PumpLoop(); // To get TrySyncSessionJob called
EXPECT_TRUE(GetThrottledTypes().HasAll(types));
// This won't cause a sync cycle because the types are throttled.
- scheduler()->ScheduleLocalNudge(zero(), types, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(types, FROM_HERE);
PumpLoop();
StopSyncScheduler();
@@ -825,14 +799,14 @@ TEST_F(SyncSchedulerTest, TypeThrottlingBlocksNudge) {
TEST_F(SyncSchedulerTest, TypeThrottlingDoesBlockOtherSources) {
UseMockDelayProvider();
EXPECT_CALL(*delay(), GetDelay(_))
- .WillRepeatedly(Return(zero()));
+ .WillRepeatedly(Return(default_delay()));
SyncShareTimes times;
TimeDelta poll(TimeDelta::FromDays(1));
TimeDelta throttle1(TimeDelta::FromSeconds(60));
scheduler()->OnReceivedLongPollIntervalUpdate(poll);
- const ModelTypeSet throttled_types(BOOKMARKS);
+ const ModelTypeSet throttled_types(THEMES);
const ModelTypeSet unthrottled_types(PREFERENCES);
::testing::InSequence seq;
@@ -845,18 +819,18 @@ TEST_F(SyncSchedulerTest, TypeThrottlingDoesBlockOtherSources) {
.RetiresOnSaturation();
StartSyncScheduler(SyncScheduler::NORMAL_MODE);
- scheduler()->ScheduleLocalNudge(zero(), throttled_types, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(throttled_types, FROM_HERE);
PumpLoop(); // To get PerformDelayedNudge called.
PumpLoop(); // To get TrySyncSessionJob called
EXPECT_TRUE(GetThrottledTypes().HasAll(throttled_types));
// Ignore invalidations for throttled types.
scheduler()->ScheduleInvalidationNudge(
- zero(), BOOKMARKS, BuildInvalidation(10, "test"), FROM_HERE);
+ THEMES, BuildInvalidation(10, "test"), FROM_HERE);
PumpLoop();
// Ignore refresh requests for throttled types.
- scheduler()->ScheduleLocalRefreshRequest(zero(), throttled_types, FROM_HERE);
+ scheduler()->ScheduleLocalRefreshRequest(throttled_types, FROM_HERE);
PumpLoop();
Mock::VerifyAndClearExpectations(syncer());
@@ -865,7 +839,7 @@ TEST_F(SyncSchedulerTest, TypeThrottlingDoesBlockOtherSources) {
EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
.WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
RecordSyncShare(&times)));
- scheduler()->ScheduleLocalNudge(zero(), unthrottled_types, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(unthrottled_types, FROM_HERE);
RunLoop();
Mock::VerifyAndClearExpectations(syncer());
@@ -880,11 +854,11 @@ TEST_F(SyncSchedulerTest, ConfigurationMode) {
StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
- const ModelTypeSet nudge_types(AUTOFILL);
- scheduler()->ScheduleLocalNudge(zero(), nudge_types, FROM_HERE);
- scheduler()->ScheduleLocalNudge(zero(), nudge_types, FROM_HERE);
+ const ModelTypeSet nudge_types(TYPED_URLS);
+ scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE);
- const ModelTypeSet config_types(BOOKMARKS);
+ const ModelTypeSet config_types(THEMES);
EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
@@ -993,7 +967,7 @@ TEST_F(BackoffTriggersSyncSchedulerTest, FailGetEncryptionKey) {
QuitLoopNowAction()));
StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
- ModelTypeSet types(BOOKMARKS);
+ ModelTypeSet types(THEMES);
CallbackCounter ready_counter;
CallbackCounter retry_counter;
ConfigurationParams params(
@@ -1012,7 +986,7 @@ TEST_F(BackoffTriggersSyncSchedulerTest, FailGetEncryptionKey) {
TEST_F(SyncSchedulerTest, BackoffDropsJobs) {
SyncShareTimes times;
TimeDelta poll(TimeDelta::FromMilliseconds(10));
- const ModelTypeSet types(BOOKMARKS);
+ const ModelTypeSet types(THEMES);
scheduler()->OnReceivedLongPollIntervalUpdate(poll);
UseMockDelayProvider();
@@ -1026,7 +1000,7 @@ TEST_F(SyncSchedulerTest, BackoffDropsJobs) {
// This nudge should fail and put us into backoff. Thanks to our mock
// GetDelay() setup above, this will be a long backoff.
- scheduler()->ScheduleLocalNudge(zero(), types, FROM_HERE);
+ scheduler()->ScheduleLocalNudge(types, FROM_HERE);
RunLoop();
// From this point forward, no SyncShare functions should be invoked.
@@ -1036,10 +1010,7 @@ TEST_F(SyncSchedulerTest, BackoffDropsJobs) {
PumpLoopFor(poll * 10);
// Try (and fail) to schedule a nudge.
- scheduler()->ScheduleLocalNudge(
- base::TimeDelta::FromMilliseconds(10),
- types,
- FROM_HERE);
+ scheduler()->ScheduleLocalNudge(types, FROM_HERE);
Mock::VerifyAndClearExpectations(syncer());
Mock::VerifyAndClearExpectations(delay());
@@ -1092,7 +1063,7 @@ TEST_F(SyncSchedulerTest, BackoffElevation) {
StartSyncScheduler(SyncScheduler::NORMAL_MODE);
// Run again with a nudge.
- scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE);
+ scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
RunLoop();
ASSERT_EQ(kMinNumSamples, times.size());
@@ -1120,7 +1091,7 @@ TEST_F(SyncSchedulerTest, BackoffRelief) {
EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
RecordSyncShare(&times)));
- scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE);
+ scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
RunLoop();
Mock::VerifyAndClearExpectations(syncer());
TimeTicks optimal_job_time = optimal_start;
@@ -1192,7 +1163,7 @@ TEST_F(SyncSchedulerTest, StartWhenNotConnected) {
Return(true)));
StartSyncScheduler(SyncScheduler::NORMAL_MODE);
- scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE);
+ scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
// Should save the nudge for until after the server is reachable.
base::MessageLoop::current()->RunUntilIdle();
@@ -1217,7 +1188,7 @@ TEST_F(SyncSchedulerTest, ServerConnectionChangeDuringBackoff) {
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
Return(true)));
- scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE);
+ scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
PumpLoop(); // To get PerformDelayedNudge called.
PumpLoop(); // Run the nudge, that will fail and schedule a quick retry.
ASSERT_TRUE(scheduler()->IsBackingOff());
@@ -1249,7 +1220,7 @@ TEST_F(SyncSchedulerTest, ConnectionChangeCanaryPreemptedByNudge) {
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
QuitLoopNowAction()));
- scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE);
+ scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
PumpLoop(); // To get PerformDelayedNudge called.
PumpLoop(); // Run the nudge, that will fail and schedule a quick retry.
@@ -1260,7 +1231,7 @@ TEST_F(SyncSchedulerTest, ConnectionChangeCanaryPreemptedByNudge) {
PumpLoop();
connection()->SetServerReachable();
connection()->UpdateConnectionStatus();
- scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE);
+ scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
base::MessageLoop::current()->RunUntilIdle();
}
@@ -1275,7 +1246,7 @@ TEST_F(SyncSchedulerTest, DoubleCanaryInConfigure) {
connection()->SetServerNotReachable();
connection()->UpdateConnectionStatus();
- ModelTypeSet model_types(BOOKMARKS);
+ ModelTypeSet model_types(THEMES);
CallbackCounter ready_counter;
CallbackCounter retry_counter;
ConfigurationParams params(
@@ -1381,8 +1352,7 @@ TEST_F(SyncSchedulerTest, ReceiveNewRetryDelay) {
base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(100);
base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(200);
- scheduler()->ScheduleLocalRefreshRequest(zero(), ModelTypeSet(BOOKMARKS),
- FROM_HERE);
+ scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
scheduler()->OnReceivedGuRetryDelay(delay1);
EXPECT_EQ(delay1, GetRetryTimerDelay());
diff --git a/sync/engine/syncer_proto_util.cc b/sync/engine/syncer_proto_util.cc
index fe2a875..44ac321 100644
--- a/sync/engine/syncer_proto_util.cc
+++ b/sync/engine/syncer_proto_util.cc
@@ -420,9 +420,10 @@ SyncerError SyncerProtoUtil::PostClientToServerMessage(
}
if (command.has_sessions_commit_delay_seconds()) {
- session->delegate()->OnReceivedSessionsCommitDelay(
- base::TimeDelta::FromSeconds(
- command.sessions_commit_delay_seconds()));
+ std::map<ModelType, base::TimeDelta> delay_map;
+ delay_map[SESSIONS] =
+ base::TimeDelta::FromSeconds(command.sessions_commit_delay_seconds());
+ session->delegate()->OnReceivedCustomNudgeDelays(delay_map);
}
if (command.has_client_invalidation_hint_buffer_size()) {
@@ -434,6 +435,22 @@ SyncerError SyncerProtoUtil::PostClientToServerMessage(
session->delegate()->OnReceivedGuRetryDelay(
base::TimeDelta::FromSeconds(command.gu_retry_delay_seconds()));
}
+
+ if (command.custom_nudge_delays_size() > 0) {
+ // Note that because this happens after the sessions_commit_delay_seconds
+ // handling, any SESSIONS value in this map will override the one in
+ // sessions_commit_delay_seconds.
+ std::map<ModelType, base::TimeDelta> delay_map;
+ for (int i = 0; i < command.custom_nudge_delays_size(); ++i) {
+ ModelType type = GetModelTypeFromSpecificsFieldNumber(
+ command.custom_nudge_delays(i).datatype_id());
+ if (ProtocolTypes().Has(type)) {
+ delay_map[type] = base::TimeDelta::FromMilliseconds(
+ command.custom_nudge_delays(i).delay_ms());
+ }
+ }
+ session->delegate()->OnReceivedCustomNudgeDelays(delay_map);
+ }
}
// Now do any special handling for the error type and decide on the return
diff --git a/sync/engine/syncer_unittest.cc b/sync/engine/syncer_unittest.cc
index ccfc014..77bc288 100644
--- a/sync/engine/syncer_unittest.cc
+++ b/sync/engine/syncer_unittest.cc
@@ -212,9 +212,15 @@ class SyncerTest : public testing::Test,
const base::TimeDelta& new_interval) OVERRIDE {
last_short_poll_interval_received_ = new_interval;
}
- virtual void OnReceivedSessionsCommitDelay(
- const base::TimeDelta& new_delay) OVERRIDE {
- last_sessions_commit_delay_seconds_ = new_delay;
+ virtual void OnReceivedCustomNudgeDelays(
+ const std::map<ModelType, base::TimeDelta>& delay_map) OVERRIDE {
+ std::map<ModelType, base::TimeDelta>::const_iterator iter =
+ delay_map.find(SESSIONS);
+ if (iter != delay_map.end() && iter->second > base::TimeDelta())
+ last_sessions_commit_delay_ = iter->second;
+ iter = delay_map.find(BOOKMARKS);
+ if (iter != delay_map.end() && iter->second > base::TimeDelta())
+ last_bookmarks_commit_delay_ = iter->second;
}
virtual void OnReceivedClientInvalidationHintBufferSize(
int size) OVERRIDE {
@@ -592,7 +598,8 @@ class SyncerTest : public testing::Test,
bool saw_syncer_event_;
base::TimeDelta last_short_poll_interval_received_;
base::TimeDelta last_long_poll_interval_received_;
- base::TimeDelta last_sessions_commit_delay_seconds_;
+ base::TimeDelta last_sessions_commit_delay_;
+ base::TimeDelta last_bookmarks_commit_delay_;
int last_client_invalidation_hint_buffer_size_;
std::vector<scoped_refptr<ModelSafeWorker> > workers_;
@@ -3606,36 +3613,41 @@ TEST_F(SyncerTest, TestClientCommandDuringUpdate) {
command->set_set_sync_poll_interval(8);
command->set_set_sync_long_poll_interval(800);
command->set_sessions_commit_delay_seconds(3141);
+ sync_pb::CustomNudgeDelay* bookmark_delay =
+ command->add_custom_nudge_delays();
+ bookmark_delay->set_datatype_id(
+ GetSpecificsFieldNumberFromModelType(BOOKMARKS));
+ bookmark_delay->set_delay_ms(950);
command->set_client_invalidation_hint_buffer_size(11);
mock_server_->AddUpdateDirectory(1, 0, "in_root", 1, 1,
foreign_cache_guid(), "-1");
mock_server_->SetGUClientCommand(command);
SyncShareNudge();
- EXPECT_TRUE(TimeDelta::FromSeconds(8) ==
- last_short_poll_interval_received_);
- EXPECT_TRUE(TimeDelta::FromSeconds(800) ==
- last_long_poll_interval_received_);
- EXPECT_TRUE(TimeDelta::FromSeconds(3141) ==
- last_sessions_commit_delay_seconds_);
+ EXPECT_EQ(TimeDelta::FromSeconds(8), last_short_poll_interval_received_);
+ EXPECT_EQ(TimeDelta::FromSeconds(800), last_long_poll_interval_received_);
+ EXPECT_EQ(TimeDelta::FromSeconds(3141), last_sessions_commit_delay_);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(950), last_bookmarks_commit_delay_);
EXPECT_EQ(11, last_client_invalidation_hint_buffer_size_);
command = new ClientCommand();
command->set_set_sync_poll_interval(180);
command->set_set_sync_long_poll_interval(190);
command->set_sessions_commit_delay_seconds(2718);
+ bookmark_delay = command->add_custom_nudge_delays();
+ bookmark_delay->set_datatype_id(
+ GetSpecificsFieldNumberFromModelType(BOOKMARKS));
+ bookmark_delay->set_delay_ms(1050);
command->set_client_invalidation_hint_buffer_size(9);
- mock_server_->AddUpdateDirectory(1, 0, "in_root", 1, 1,
- foreign_cache_guid(), "-1");
+ mock_server_->AddUpdateDirectory(
+ 1, 0, "in_root", 1, 1, foreign_cache_guid(), "-1");
mock_server_->SetGUClientCommand(command);
SyncShareNudge();
- EXPECT_TRUE(TimeDelta::FromSeconds(180) ==
- last_short_poll_interval_received_);
- EXPECT_TRUE(TimeDelta::FromSeconds(190) ==
- last_long_poll_interval_received_);
- EXPECT_TRUE(TimeDelta::FromSeconds(2718) ==
- last_sessions_commit_delay_seconds_);
+ EXPECT_EQ(TimeDelta::FromSeconds(180), last_short_poll_interval_received_);
+ EXPECT_EQ(TimeDelta::FromSeconds(190), last_long_poll_interval_received_);
+ EXPECT_EQ(TimeDelta::FromSeconds(2718), last_sessions_commit_delay_);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(1050), last_bookmarks_commit_delay_);
EXPECT_EQ(9, last_client_invalidation_hint_buffer_size_);
}
@@ -3646,34 +3658,39 @@ TEST_F(SyncerTest, TestClientCommandDuringCommit) {
command->set_set_sync_poll_interval(8);
command->set_set_sync_long_poll_interval(800);
command->set_sessions_commit_delay_seconds(3141);
+ sync_pb::CustomNudgeDelay* bookmark_delay =
+ command->add_custom_nudge_delays();
+ bookmark_delay->set_datatype_id(
+ GetSpecificsFieldNumberFromModelType(BOOKMARKS));
+ bookmark_delay->set_delay_ms(950);
command->set_client_invalidation_hint_buffer_size(11);
CreateUnsyncedDirectory("X", "id_X");
mock_server_->SetCommitClientCommand(command);
SyncShareNudge();
- EXPECT_TRUE(TimeDelta::FromSeconds(8) ==
- last_short_poll_interval_received_);
- EXPECT_TRUE(TimeDelta::FromSeconds(800) ==
- last_long_poll_interval_received_);
- EXPECT_TRUE(TimeDelta::FromSeconds(3141) ==
- last_sessions_commit_delay_seconds_);
+ EXPECT_EQ(TimeDelta::FromSeconds(8), last_short_poll_interval_received_);
+ EXPECT_EQ(TimeDelta::FromSeconds(800), last_long_poll_interval_received_);
+ EXPECT_EQ(TimeDelta::FromSeconds(3141), last_sessions_commit_delay_);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(950), last_bookmarks_commit_delay_);
EXPECT_EQ(11, last_client_invalidation_hint_buffer_size_);
command = new ClientCommand();
command->set_set_sync_poll_interval(180);
command->set_set_sync_long_poll_interval(190);
command->set_sessions_commit_delay_seconds(2718);
+ bookmark_delay = command->add_custom_nudge_delays();
+ bookmark_delay->set_datatype_id(
+ GetSpecificsFieldNumberFromModelType(BOOKMARKS));
+ bookmark_delay->set_delay_ms(1050);
command->set_client_invalidation_hint_buffer_size(9);
CreateUnsyncedDirectory("Y", "id_Y");
mock_server_->SetCommitClientCommand(command);
SyncShareNudge();
- EXPECT_TRUE(TimeDelta::FromSeconds(180) ==
- last_short_poll_interval_received_);
- EXPECT_TRUE(TimeDelta::FromSeconds(190) ==
- last_long_poll_interval_received_);
- EXPECT_TRUE(TimeDelta::FromSeconds(2718) ==
- last_sessions_commit_delay_seconds_);
+ EXPECT_EQ(TimeDelta::FromSeconds(180), last_short_poll_interval_received_);
+ EXPECT_EQ(TimeDelta::FromSeconds(190), last_long_poll_interval_received_);
+ EXPECT_EQ(TimeDelta::FromSeconds(2718), last_sessions_commit_delay_);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(1050), last_bookmarks_commit_delay_);
EXPECT_EQ(9, last_client_invalidation_hint_buffer_size_);
}
diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc
index f0fecbc..23ac6b2 100644
--- a/sync/internal_api/sync_manager_impl.cc
+++ b/sync/internal_api/sync_manager_impl.cc
@@ -61,12 +61,6 @@ using syncable::UNIQUE_POSITION;
namespace {
-// Delays for syncer nudges.
-static const int kDefaultNudgeDelayMilliseconds = 200;
-static const int kSlowNudgeDelayMilliseconds = 2000;
-static const int kSyncRefreshDelayMsec = 500;
-static const int kSyncSchedulerDelayMsec = 250;
-
GetUpdatesCallerInfo::GetUpdatesSource GetSourceFromReason(
ConfigureReason reason) {
switch (reason) {
@@ -89,84 +83,6 @@ GetUpdatesCallerInfo::GetUpdatesSource GetSourceFromReason(
} // namespace
-// A class to calculate nudge delays for types.
-class NudgeStrategy {
- public:
- static TimeDelta GetNudgeDelayTimeDelta(const ModelType& model_type,
- SyncManagerImpl* core) {
- NudgeDelayStrategy delay_type = GetNudgeDelayStrategy(model_type);
- return GetNudgeDelayTimeDeltaFromType(delay_type,
- model_type,
- core);
- }
-
- private:
- // Possible types of nudge delay for datatypes.
- // Note: These are just hints. If a sync happens then all dirty entries
- // would be committed as part of the sync.
- enum NudgeDelayStrategy {
- // Sync right away.
- IMMEDIATE,
-
- // Sync this change while syncing another change.
- ACCOMPANY_ONLY,
-
- // The datatype does not use one of the predefined wait times but defines
- // its own wait time logic for nudge.
- CUSTOM,
- };
-
- static NudgeDelayStrategy GetNudgeDelayStrategy(const ModelType& type) {
- switch (type) {
- case AUTOFILL:
- return ACCOMPANY_ONLY;
- case BOOKMARKS:
- case PREFERENCES:
- case SESSIONS:
- case FAVICON_IMAGES:
- case FAVICON_TRACKING:
- return CUSTOM;
- default:
- return IMMEDIATE;
- }
- }
-
- static TimeDelta GetNudgeDelayTimeDeltaFromType(
- const NudgeDelayStrategy& delay_type, const ModelType& model_type,
- const SyncManagerImpl* core) {
- CHECK(core);
- TimeDelta delay = TimeDelta::FromMilliseconds(
- kDefaultNudgeDelayMilliseconds);
- switch (delay_type) {
- case IMMEDIATE:
- delay = TimeDelta::FromMilliseconds(
- kDefaultNudgeDelayMilliseconds);
- break;
- case ACCOMPANY_ONLY:
- delay = TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds);
- break;
- case CUSTOM:
- switch (model_type) {
- case BOOKMARKS:
- case PREFERENCES:
- delay = TimeDelta::FromMilliseconds(kSlowNudgeDelayMilliseconds);
- break;
- case SESSIONS:
- case FAVICON_IMAGES:
- case FAVICON_TRACKING:
- delay = core->scheduler()->GetSessionsCommitDelay();
- break;
- default:
- NOTREACHED();
- }
- break;
- default:
- NOTREACHED();
- }
- return delay;
- }
-};
-
SyncManagerImpl::SyncManagerImpl(const std::string& name)
: name_(name),
change_delegate_(NULL),
@@ -882,23 +798,12 @@ void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncer(
}
}
-TimeDelta SyncManagerImpl::GetNudgeDelayTimeDelta(
- const ModelType& model_type) {
- return NudgeStrategy::GetNudgeDelayTimeDelta(model_type, this);
-}
-
void SyncManagerImpl::RequestNudgeForDataTypes(
const tracked_objects::Location& nudge_location,
ModelTypeSet types) {
debug_info_event_listener_.OnNudgeFromDatatype(types.First().Get());
- // TODO(lipalani) : Calculate the nudge delay based on all types.
- base::TimeDelta nudge_delay = NudgeStrategy::GetNudgeDelayTimeDelta(
- types.First().Get(),
- this);
- scheduler_->ScheduleLocalNudge(nudge_delay,
- types,
- nudge_location);
+ scheduler_->ScheduleLocalNudge(types, nudge_location);
}
void SyncManagerImpl::NudgeForInitialDownload(syncer::ModelType type) {
@@ -998,7 +903,6 @@ void SyncManagerImpl::OnIncomingInvalidation(
DCHECK(thread_checker_.CalledOnValidThread());
scheduler_->ScheduleInvalidationNudge(
- TimeDelta::FromMilliseconds(kSyncSchedulerDelayMsec),
type,
invalidation.Pass(),
FROM_HERE);
@@ -1010,7 +914,6 @@ void SyncManagerImpl::RefreshTypes(ModelTypeSet types) {
LOG(WARNING) << "Sync received refresh request with no types specified.";
} else {
scheduler_->ScheduleLocalRefreshRequest(
- TimeDelta::FromMilliseconds(kSyncRefreshDelayMsec),
types, FROM_HERE);
}
}
@@ -1144,14 +1047,4 @@ void SyncManagerImpl::RequestEmitDebugInfo() {
model_type_registry_->RequestEmitDebugInfo();
}
-// static.
-int SyncManagerImpl::GetDefaultNudgeDelay() {
- return kDefaultNudgeDelayMilliseconds;
-}
-
-// static.
-int SyncManagerImpl::GetSlowNudgeDelay() {
- return kSlowNudgeDelayMilliseconds;
-}
-
} // namespace syncer
diff --git a/sync/internal_api/sync_manager_impl.h b/sync/internal_api/sync_manager_impl.h
index fa1fe11..b2c7a45 100644
--- a/sync/internal_api/sync_manager_impl.h
+++ b/sync/internal_api/sync_manager_impl.h
@@ -130,9 +130,6 @@ class SYNC_EXPORT_PRIVATE SyncManagerImpl
PassphraseType type,
base::Time explicit_passphrase_time) OVERRIDE;
- static int GetDefaultNudgeDelay();
- static int GetSlowNudgeDelay();
-
// SyncEngineEventListener implementation.
virtual void OnSyncCycleEvent(const SyncCycleEvent& event) OVERRIDE;
virtual void OnActionableError(const SyncProtocolError& error) OVERRIDE;
diff --git a/sync/internal_api/sync_manager_impl_unittest.cc b/sync/internal_api/sync_manager_impl_unittest.cc
index 5d730f3..408d739 100644
--- a/sync/internal_api/sync_manager_impl_unittest.cc
+++ b/sync/internal_api/sync_manager_impl_unittest.cc
@@ -1609,23 +1609,6 @@ TEST_F(SyncManagerTest, SetPassphraseWithEmptyPasswordNode) {
}
}
-TEST_F(SyncManagerTest, NudgeDelayTest) {
- EXPECT_EQ(
- sync_manager_.GetNudgeDelayTimeDelta(BOOKMARKS),
- base::TimeDelta::FromMilliseconds(SyncManagerImpl::GetSlowNudgeDelay()));
-
- EXPECT_EQ(sync_manager_.GetNudgeDelayTimeDelta(AUTOFILL),
- base::TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds));
-
- EXPECT_EQ(
- sync_manager_.GetNudgeDelayTimeDelta(PREFERENCES),
- base::TimeDelta::FromMilliseconds(SyncManagerImpl::GetSlowNudgeDelay()));
-
- EXPECT_EQ(sync_manager_.GetNudgeDelayTimeDelta(EXTENSIONS),
- base::TimeDelta::FromMilliseconds(
- SyncManagerImpl::GetDefaultNudgeDelay()));
-}
-
// Friended by WriteNode, so can't be in an anonymouse namespace.
TEST_F(SyncManagerTest, EncryptBookmarksWithLegacyData) {
EXPECT_TRUE(SetUpEncryption(WRITE_TO_NIGORI, DEFAULT_ENCRYPTION));
diff --git a/sync/protocol/client_commands.proto b/sync/protocol/client_commands.proto
index e36914a..fa9c714 100644
--- a/sync/protocol/client_commands.proto
+++ b/sync/protocol/client_commands.proto
@@ -14,6 +14,11 @@ option retain_unknown_fields = true;
package sync_pb;
+message CustomNudgeDelay {
+ optional int32 datatype_id = 1; // Datatype id.
+ optional int32 delay_ms = 2; // Delay in milliseconds.
+};
+
message ClientCommand {
// Time to wait before sending any requests to the server.
optional int32 set_sync_poll_interval = 1; // in seconds
@@ -21,9 +26,8 @@ message ClientCommand {
optional int32 max_commit_batch_size = 3;
- // Number of seconds to delay between a sessions
- // action and sending a commit message to the
- // server
+ // Number of seconds to delay between a sessions action and sending a commit
+ // message to the server. Can be overridden by |custom_nudge_delays|.
optional int32 sessions_commit_delay_seconds = 4;
// Number of seconds to delay before the throttled client should retry.
@@ -34,4 +38,10 @@ message ClientCommand {
// Time to wait before issuing a retry GU.
optional int32 gu_retry_delay_seconds = 7;
+
+ // A dictionary of custom nudge delays.
+ // Note: if a SESSIONS value is present, this will override
+ // |sessions_commit_delay_seconds|
+ // New in M39.
+ repeated CustomNudgeDelay custom_nudge_delays = 8;
};
diff --git a/sync/sessions/data_type_tracker.cc b/sync/sessions/data_type_tracker.cc
index 12b53e9..da50bbf 100644
--- a/sync/sessions/data_type_tracker.cc
+++ b/sync/sessions/data_type_tracker.cc
@@ -20,8 +20,9 @@ DataTypeTracker::DataTypeTracker()
DataTypeTracker::~DataTypeTracker() { }
-void DataTypeTracker::RecordLocalChange() {
+base::TimeDelta DataTypeTracker::RecordLocalChange() {
local_nudge_count_++;
+ return nudge_delay_;
}
void DataTypeTracker::RecordLocalRefreshRequest() {
@@ -218,5 +219,9 @@ void DataTypeTracker::UpdateThrottleState(base::TimeTicks now) {
}
}
+void DataTypeTracker::UpdateLocalNudgeDelay(base::TimeDelta delay) {
+ nudge_delay_ = delay;
+}
+
} // namespace sessions
} // namespace syncer
diff --git a/sync/sessions/data_type_tracker.h b/sync/sessions/data_type_tracker.h
index 7b0aba8..c53f393 100644
--- a/sync/sessions/data_type_tracker.h
+++ b/sync/sessions/data_type_tracker.h
@@ -31,7 +31,8 @@ class DataTypeTracker {
// constructor and assignment operator.
// Tracks that a local change has been made to this type.
- void RecordLocalChange();
+ // Returns the current local change nudge delay for this type.
+ base::TimeDelta RecordLocalChange();
// Tracks that a local refresh request has been made for this type.
void RecordLocalRefreshRequest();
@@ -96,6 +97,9 @@ class DataTypeTracker {
// Unthrottles the type if |now| >= the throttle expiry time.
void UpdateThrottleState(base::TimeTicks now);
+ // Update the local change nudge delay for this type.
+ void UpdateLocalNudgeDelay(base::TimeDelta delay);
+
private:
// Number of local change nudges received for this type since the last
// successful sync cycle.
@@ -125,6 +129,10 @@ class DataTypeTracker {
// A helper to keep track invalidations we dropped due to overflow.
scoped_ptr<InvalidationInterface> last_dropped_invalidation_;
+ // The amount of time to delay a sync cycle by when a local change for this
+ // type occurs.
+ base::TimeDelta nudge_delay_;
+
DISALLOW_COPY_AND_ASSIGN(DataTypeTracker);
};
diff --git a/sync/sessions/nudge_tracker.cc b/sync/sessions/nudge_tracker.cc
index d9aaec6..9c62b07 100644
--- a/sync/sessions/nudge_tracker.cc
+++ b/sync/sessions/nudge_tracker.cc
@@ -5,17 +5,58 @@
#include "sync/sessions/nudge_tracker.h"
#include "base/basictypes.h"
+#include "sync/internal_api/public/engine/polling_constants.h"
#include "sync/protocol/sync.pb.h"
namespace syncer {
namespace sessions {
+namespace {
+
+// Delays for syncer nudges.
+const int kDefaultNudgeDelayMilliseconds = 200;
+const int kSlowNudgeDelayMilliseconds = 2000;
+const int kDefaultSessionsCommitDelaySeconds = 10;
+const int kSyncRefreshDelayMilliseconds = 500;
+const int kSyncSchedulerDelayMilliseconds = 250;
+
+base::TimeDelta GetDefaultDelayForType(ModelType model_type,
+ base::TimeDelta minimum_delay) {
+ switch (model_type) {
+ case AUTOFILL:
+ // Accompany types rely on nudges from other types, and hence have long
+ // nudge delays.
+ return base::TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds);
+ case BOOKMARKS:
+ case PREFERENCES:
+ // Types with sometimes automatic changes get longer delays to allow more
+ // coalescing.
+ return base::TimeDelta::FromMilliseconds(kSlowNudgeDelayMilliseconds);
+ case SESSIONS:
+ case FAVICON_IMAGES:
+ case FAVICON_TRACKING:
+ // Types with navigation triggered changes get longer delays to allow more
+ // coalescing.
+ return base::TimeDelta::FromSeconds(kDefaultSessionsCommitDelaySeconds);
+ default:
+ return minimum_delay;
+ }
+}
+
+} // namespace
+
size_t NudgeTracker::kDefaultMaxPayloadsPerType = 10;
NudgeTracker::NudgeTracker()
: type_tracker_deleter_(&type_trackers_),
invalidations_enabled_(false),
- invalidations_out_of_sync_(true) {
+ invalidations_out_of_sync_(true),
+ minimum_local_nudge_delay_(
+ base::TimeDelta::FromMilliseconds(kDefaultNudgeDelayMilliseconds)),
+ local_refresh_nudge_delay_(
+ base::TimeDelta::FromMilliseconds(kSyncRefreshDelayMilliseconds)),
+ remote_invalidation_nudge_delay_(
+ base::TimeDelta::FromMilliseconds(kSyncSchedulerDelayMilliseconds)) {
ModelTypeSet protocol_types = ProtocolTypes();
// Default initialize all the type trackers.
for (ModelTypeSet::Iterator it = protocol_types.First(); it.Good();
@@ -80,30 +121,45 @@ void NudgeTracker::RecordSuccessfulSyncCycle() {
}
}
-void NudgeTracker::RecordLocalChange(ModelTypeSet types) {
+base::TimeDelta NudgeTracker::RecordLocalChange(ModelTypeSet types) {
+ // Start with the longest delay.
+ base::TimeDelta delay =
+ base::TimeDelta::FromMilliseconds(kDefaultShortPollIntervalSeconds);
for (ModelTypeSet::Iterator type_it = types.First(); type_it.Good();
type_it.Inc()) {
TypeTrackerMap::iterator tracker_it = type_trackers_.find(type_it.Get());
DCHECK(tracker_it != type_trackers_.end());
- tracker_it->second->RecordLocalChange();
+
+ // Only if the type tracker has a valid delay (non-zero) that is shorter
+ // than the calculated delay do we update the calculated delay.
+ base::TimeDelta type_delay = tracker_it->second->RecordLocalChange();
+ if (type_delay == base::TimeDelta()) {
+ type_delay = GetDefaultDelayForType(type_it.Get(),
+ minimum_local_nudge_delay_);
+ }
+ if (type_delay < delay)
+ delay = type_delay;
}
+ return delay;
}
-void NudgeTracker::RecordLocalRefreshRequest(ModelTypeSet types) {
+base::TimeDelta NudgeTracker::RecordLocalRefreshRequest(ModelTypeSet types) {
for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
TypeTrackerMap::iterator tracker_it = type_trackers_.find(it.Get());
DCHECK(tracker_it != type_trackers_.end());
tracker_it->second->RecordLocalRefreshRequest();
}
+ return local_refresh_nudge_delay_;
}
-void NudgeTracker::RecordRemoteInvalidation(
+base::TimeDelta NudgeTracker::RecordRemoteInvalidation(
syncer::ModelType type,
scoped_ptr<InvalidationInterface> invalidation) {
// Forward the invalidations to the proper recipient.
TypeTrackerMap::iterator tracker_it = type_trackers_.find(type);
DCHECK(tracker_it != type_trackers_.end());
tracker_it->second->RecordRemoteInvalidation(invalidation.Pass());
+ return remote_invalidation_nudge_delay_;
}
void NudgeTracker::RecordInitialSyncRequired(syncer::ModelType type) {
@@ -317,5 +373,31 @@ void NudgeTracker::SetNextRetryTime(base::TimeTicks retry_time) {
next_retry_time_ = retry_time;
}
+void NudgeTracker::OnReceivedCustomNudgeDelays(
+ const std::map<ModelType, base::TimeDelta>& delay_map) {
+ for (std::map<ModelType, base::TimeDelta>::const_iterator iter =
+ delay_map.begin();
+ iter != delay_map.end();
+ ++iter) {
+ ModelType type = iter->first;
+ DCHECK(syncer::ProtocolTypes().Has(type));
+ TypeTrackerMap::iterator type_iter = type_trackers_.find(type);
+ if (type_iter == type_trackers_.end())
+ continue;
+
+ if (iter->second > minimum_local_nudge_delay_) {
+ type_iter->second->UpdateLocalNudgeDelay(iter->second);
+ } else {
+ type_iter->second->UpdateLocalNudgeDelay(
+ GetDefaultDelayForType(type,
+ minimum_local_nudge_delay_));
+ }
+ }
+}
+
+void NudgeTracker::SetDefaultNudgeDelay(base::TimeDelta nudge_delay) {
+ minimum_local_nudge_delay_ = nudge_delay;
+}
+
} // namespace sessions
} // namespace syncer
diff --git a/sync/sessions/nudge_tracker.h b/sync/sessions/nudge_tracker.h
index 0397c5d..7d6cf0f8 100644
--- a/sync/sessions/nudge_tracker.h
+++ b/sync/sessions/nudge_tracker.h
@@ -12,6 +12,7 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
#include "sync/base/sync_export.h"
#include "sync/internal_api/public/base/invalidation_interface.h"
#include "sync/internal_api/public/base/model_type.h"
@@ -53,14 +54,18 @@ class SYNC_EXPORT_PRIVATE NudgeTracker {
void RecordSuccessfulSyncCycle();
// Takes note of a local change.
- void RecordLocalChange(ModelTypeSet types);
+ // Returns the shortest nudge delay from the tracker of each type in |types|.
+ base::TimeDelta RecordLocalChange(ModelTypeSet types);
// Takes note of a locally issued request to refresh a data type.
- void RecordLocalRefreshRequest(ModelTypeSet types);
+ // Returns the current nudge delay for a local refresh.
+ base::TimeDelta RecordLocalRefreshRequest(ModelTypeSet types);
// Takes note of the receipt of an invalidation notice from the server.
- void RecordRemoteInvalidation(syncer::ModelType type,
- scoped_ptr<InvalidationInterface> invalidation);
+ // Returns the current nudge delay for a remote invalidation.
+ base::TimeDelta RecordRemoteInvalidation(
+ syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> invalidation);
// Take note that an initial sync is pending for this type.
void RecordInitialSyncRequired(syncer::ModelType type);
@@ -141,6 +146,13 @@ class SYNC_EXPORT_PRIVATE NudgeTracker {
// SetSyncCycleStartTime() is called at the start of the *next* sync cycle.
void SetNextRetryTime(base::TimeTicks next_retry_time);
+ // Update the per-datatype local change nudge delays.
+ void OnReceivedCustomNudgeDelays(
+ const std::map<ModelType, base::TimeDelta>& delay_map);
+
+ // Update the default nudge delay.
+ void SetDefaultNudgeDelay(base::TimeDelta nudge_delay);
+
private:
typedef std::map<ModelType, DataTypeTracker*> TypeTrackerMap;
@@ -186,6 +198,11 @@ class SYNC_EXPORT_PRIVATE NudgeTracker {
// currently in a sync cycle.
base::TimeTicks sync_cycle_start_time_;
+ // Nudge delays for various events.
+ base::TimeDelta minimum_local_nudge_delay_;
+ base::TimeDelta local_refresh_nudge_delay_;
+ base::TimeDelta remote_invalidation_nudge_delay_;
+
DISALLOW_COPY_AND_ASSIGN(NudgeTracker);
};
diff --git a/sync/sessions/nudge_tracker_unittest.cc b/sync/sessions/nudge_tracker_unittest.cc
index 0b00d5e..50b596b 100644
--- a/sync/sessions/nudge_tracker_unittest.cc
+++ b/sync/sessions/nudge_tracker_unittest.cc
@@ -728,6 +728,85 @@ TEST_F(NudgeTrackerTest, IsRetryRequired_FailedCycleIncludesUpdate) {
nudge_tracker_.RecordSuccessfulSyncCycle();
}
+// Test the default nudge delays for various types.
+TEST_F(NudgeTrackerTest, NudgeDelayTest) {
+ // Set to a known value to compare against.
+ nudge_tracker_.SetDefaultNudgeDelay(base::TimeDelta());
+
+ // Bookmarks and preference both have "slow nudge" delays.
+ EXPECT_EQ(nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)),
+ nudge_tracker_.RecordLocalChange(ModelTypeSet(PREFERENCES)));
+
+ // Typed URLs has a default delay.
+ EXPECT_EQ(nudge_tracker_.RecordLocalChange(ModelTypeSet(TYPED_URLS)),
+ base::TimeDelta());
+
+ // "Slow nudge" delays are longer than the default.
+ EXPECT_GT(nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)),
+ base::TimeDelta());
+
+ // Sessions is longer than "slow nudge".
+ EXPECT_GT(nudge_tracker_.RecordLocalChange(ModelTypeSet(SESSIONS)),
+ nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)));
+
+ // Favicons have the same delay as sessions.
+ EXPECT_EQ(nudge_tracker_.RecordLocalChange(ModelTypeSet(SESSIONS)),
+ nudge_tracker_.RecordLocalChange(ModelTypeSet(FAVICON_TRACKING)));
+
+ // Autofill has the longer delay of all.
+ EXPECT_GT(nudge_tracker_.RecordLocalChange(ModelTypeSet(AUTOFILL)),
+ nudge_tracker_.RecordLocalChange(ModelTypeSet(SESSIONS)));
+
+ // A nudge with no types takes the longest delay.
+ EXPECT_EQ(nudge_tracker_.RecordLocalChange(ModelTypeSet(AUTOFILL)),
+ nudge_tracker_.RecordLocalChange(ModelTypeSet()));
+
+ // The actual nudge delay should be the shortest of the set.
+ EXPECT_EQ(
+ nudge_tracker_.RecordLocalChange(ModelTypeSet(TYPED_URLS)),
+ nudge_tracker_.RecordLocalChange(ModelTypeSet(TYPED_URLS, AUTOFILL)));
+}
+
+// Test that custom nudge delays are used over the defaults.
+TEST_F(NudgeTrackerTest, CustomDelayTest) {
+ // Set some custom delays.
+ std::map<ModelType, base::TimeDelta> delay_map;
+ delay_map[BOOKMARKS] = base::TimeDelta::FromSeconds(10);
+ delay_map[SESSIONS] = base::TimeDelta::FromSeconds(2);
+ nudge_tracker_.OnReceivedCustomNudgeDelays(delay_map);
+
+ // Only those with custom delays should be affected, not another type.
+ EXPECT_NE(nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)),
+ nudge_tracker_.RecordLocalChange(ModelTypeSet(PREFERENCES)));
+
+ EXPECT_EQ(base::TimeDelta::FromSeconds(10),
+ nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)));
+ EXPECT_EQ(base::TimeDelta::FromSeconds(2),
+ nudge_tracker_.RecordLocalChange(ModelTypeSet(SESSIONS)));
+}
+
+// Check that custom nudge delays can never result in a value shorter than the
+// minimum nudge delay.
+TEST_F(NudgeTrackerTest, NoTypesShorterThanDefault) {
+ // Set delay to a known value.
+ nudge_tracker_.SetDefaultNudgeDelay(base::TimeDelta::FromMilliseconds(500));
+
+ std::map<ModelType, base::TimeDelta> delay_map;
+ ModelTypeSet protocol_types = syncer::ProtocolTypes();
+ for (ModelTypeSet::Iterator iter = protocol_types.First(); iter.Good();
+ iter.Inc()) {
+ delay_map[iter.Get()] = base::TimeDelta();
+ }
+ nudge_tracker_.OnReceivedCustomNudgeDelays(delay_map);
+
+ // All types should still have a nudge greater than or equal to the minimum.
+ for (ModelTypeSet::Iterator iter = protocol_types.First(); iter.Good();
+ iter.Inc()) {
+ EXPECT_GE(nudge_tracker_.RecordLocalChange(ModelTypeSet(iter.Get())),
+ base::TimeDelta::FromMilliseconds(500));
+ }
+}
+
class NudgeTrackerAckTrackingTest : public NudgeTrackerTest {
public:
NudgeTrackerAckTrackingTest() {}
diff --git a/sync/sessions/sync_session.h b/sync/sessions/sync_session.h
index d61a792..fd20132 100644
--- a/sync/sessions/sync_session.h
+++ b/sync/sessions/sync_session.h
@@ -71,10 +71,9 @@ class SYNC_EXPORT_PRIVATE SyncSession {
virtual void OnReceivedLongPollIntervalUpdate(
const base::TimeDelta& new_interval) = 0;
- // The client has been instructed to change its sessions commit
- // delay.
- virtual void OnReceivedSessionsCommitDelay(
- const base::TimeDelta& new_delay) = 0;
+ // The client has been instructed to change a nudge delay.
+ virtual void OnReceivedCustomNudgeDelays(
+ const std::map<ModelType, base::TimeDelta>& nudge_delays) = 0;
// Called for the syncer to respond to the error sent by the server.
virtual void OnSyncProtocolError(
diff --git a/sync/sessions/test_util.cc b/sync/sessions/test_util.cc
index 0555d86..1163ea7 100644
--- a/sync/sessions/test_util.cc
+++ b/sync/sessions/test_util.cc
@@ -122,7 +122,9 @@ void SimulateSessionsCommitDelayUpdateImpl(
sessions::SyncSession* session,
const base::TimeDelta& new_delay) {
SimulateNormalSuccess(requested_types, nudge_tracker, session);
- session->delegate()->OnReceivedSessionsCommitDelay(new_delay);
+ std::map<ModelType, base::TimeDelta> delay_map;
+ delay_map[SESSIONS] = new_delay;
+ session->delegate()->OnReceivedCustomNudgeDelays(delay_map);
}
void SimulateGuRetryDelayCommandImpl(sessions::SyncSession* session,
diff --git a/sync/test/engine/fake_sync_scheduler.cc b/sync/test/engine/fake_sync_scheduler.cc
index 817b37c99..a9b6f57 100644
--- a/sync/test/engine/fake_sync_scheduler.cc
+++ b/sync/test/engine/fake_sync_scheduler.cc
@@ -17,19 +17,16 @@ void FakeSyncScheduler::Stop() {
}
void FakeSyncScheduler::ScheduleLocalNudge(
- const base::TimeDelta& desired_delay,
ModelTypeSet types,
const tracked_objects::Location& nudge_location) {
}
void FakeSyncScheduler::ScheduleLocalRefreshRequest(
- const base::TimeDelta& desired_delay,
ModelTypeSet types,
const tracked_objects::Location& nudge_location) {
}
void FakeSyncScheduler::ScheduleInvalidationNudge(
- const base::TimeDelta& desired_delay,
syncer::ModelType type,
scoped_ptr<InvalidationInterface> interface,
const tracked_objects::Location& nudge_location) {
@@ -46,10 +43,6 @@ void FakeSyncScheduler::ScheduleInitialSyncNudge(syncer::ModelType model_type) {
void FakeSyncScheduler::SetNotificationsEnabled(bool notifications_enabled) {
}
-base::TimeDelta FakeSyncScheduler::GetSessionsCommitDelay() const {
- return base::TimeDelta();
-}
-
void FakeSyncScheduler::OnCredentialsUpdated() {
}
@@ -72,15 +65,15 @@ bool FakeSyncScheduler::IsCurrentlyThrottled() {
}
void FakeSyncScheduler::OnReceivedShortPollIntervalUpdate(
- const base::TimeDelta& new_interval) {
+ const base::TimeDelta& new_interval) {
}
void FakeSyncScheduler::OnReceivedLongPollIntervalUpdate(
- const base::TimeDelta& new_interval) {
+ const base::TimeDelta& new_interval) {
}
-void FakeSyncScheduler::OnReceivedSessionsCommitDelay(
- const base::TimeDelta& new_delay) {
+void FakeSyncScheduler::OnReceivedCustomNudgeDelays(
+ const std::map<ModelType, base::TimeDelta>& nudge_delays) {
}
void FakeSyncScheduler::OnReceivedClientInvalidationHintBufferSize(int size) {
diff --git a/sync/test/engine/fake_sync_scheduler.h b/sync/test/engine/fake_sync_scheduler.h
index 6800033..6abc402 100644
--- a/sync/test/engine/fake_sync_scheduler.h
+++ b/sync/test/engine/fake_sync_scheduler.h
@@ -22,15 +22,12 @@ class FakeSyncScheduler : public SyncScheduler {
virtual void Start(Mode mode) OVERRIDE;
virtual void Stop() OVERRIDE;
virtual void ScheduleLocalNudge(
- const base::TimeDelta& desired_delay,
ModelTypeSet types,
const tracked_objects::Location& nudge_location) OVERRIDE;
virtual void ScheduleLocalRefreshRequest(
- const base::TimeDelta& desired_delay,
ModelTypeSet types,
const tracked_objects::Location& nudge_location) OVERRIDE;
virtual void ScheduleInvalidationNudge(
- const base::TimeDelta& desired_delay,
syncer::ModelType type,
scoped_ptr<InvalidationInterface> interface,
const tracked_objects::Location& nudge_location) OVERRIDE;
@@ -39,7 +36,6 @@ class FakeSyncScheduler : public SyncScheduler {
virtual void ScheduleInitialSyncNudge(syncer::ModelType model_type) OVERRIDE;
virtual void SetNotificationsEnabled(bool notifications_enabled) OVERRIDE;
- virtual base::TimeDelta GetSessionsCommitDelay() const OVERRIDE;
virtual void OnCredentialsUpdated() OVERRIDE;
virtual void OnConnectionStatusChange() OVERRIDE;
@@ -54,8 +50,8 @@ class FakeSyncScheduler : public SyncScheduler {
const base::TimeDelta& new_interval) OVERRIDE;
virtual void OnReceivedLongPollIntervalUpdate(
const base::TimeDelta& new_interval) OVERRIDE;
- virtual void OnReceivedSessionsCommitDelay(
- const base::TimeDelta& new_delay) OVERRIDE;
+ virtual void OnReceivedCustomNudgeDelays(
+ const std::map<ModelType, base::TimeDelta>& nudge_delays) OVERRIDE;
virtual void OnReceivedClientInvalidationHintBufferSize(int size) OVERRIDE;
virtual void OnSyncProtocolError(
const SyncProtocolError& error) OVERRIDE;