Index: trunk/src/chrome/browser/sync_file_system/drive_file_sync_service.cc |
=================================================================== |
--- trunk/src/chrome/browser/sync_file_system/drive_file_sync_service.cc (revision 195487) |
+++ trunk/src/chrome/browser/sync_file_system/drive_file_sync_service.cc (working copy) |
@@ -46,6 +46,14 @@ |
const base::FilePath::CharType kSyncFileSystemDir[] = |
FILE_PATH_LITERAL("Sync FileSystem"); |
+// Incremental sync polling interval. |
+// TODO(calvinlo): Improve polling algorithm dependent on whether push |
+// notifications are on or off. |
+const int64 kMinimumPollingDelaySeconds = 5; |
+const int64 kMaximumPollingDelaySeconds = 10 * 60; // 10 min |
+const int64 kPollingDelaySecondsWithNotification = 4 * 60 * 60; // 4 hr |
+const double kDelayMultiplier = 1.6; |
+ |
bool CreateTemporaryFile(const base::FilePath& dir_path, |
base::FilePath* temp_file) { |
return file_util::CreateDirectory(dir_path) && |
@@ -267,6 +275,7 @@ |
state_(REMOTE_SERVICE_OK), |
sync_enabled_(true), |
largest_fetched_changestamp_(0), |
+ polling_delay_seconds_(kMinimumPollingDelaySeconds), |
may_have_unfetched_changes_(false), |
remote_change_processor_(NULL), |
conflict_resolution_(kDefaultPolicy), |
@@ -559,6 +568,11 @@ |
FOR_EACH_OBSERVER( |
Observer, service_observers_, |
OnRemoteServiceStateUpdated(GetCurrentState(), status_message)); |
+ |
+ if (GetCurrentState() == REMOTE_SERVICE_OK) { |
+ UpdatePollingDelay(kMinimumPollingDelaySeconds); |
+ SchedulePolling(); |
+ } |
} |
SyncStatusCode DriveFileSyncService::SetConflictResolutionPolicy( |
@@ -629,6 +643,7 @@ |
FOR_EACH_OBSERVER( |
Observer, service_observers_, |
OnRemoteServiceStateUpdated(GetCurrentState(), "Authenticated")); |
+ UpdatePollingDelay(kMinimumPollingDelaySeconds); |
may_have_unfetched_changes_ = true; |
MaybeStartFetchChanges(); |
@@ -644,6 +659,7 @@ |
FOR_EACH_OBSERVER( |
Observer, service_observers_, |
OnRemoteServiceStateUpdated(GetCurrentState(), "Network connected")); |
+ UpdatePollingDelay(kMinimumPollingDelaySeconds); |
may_have_unfetched_changes_ = true; |
MaybeStartFetchChanges(); |
@@ -660,6 +676,7 @@ |
state_(REMOTE_SERVICE_OK), |
sync_enabled_(true), |
largest_fetched_changestamp_(0), |
+ polling_delay_seconds_(-1), |
may_have_unfetched_changes_(false), |
remote_change_processor_(NULL), |
conflict_resolution_(kDefaultPolicy), |
@@ -710,6 +727,10 @@ |
RemoteServiceState old_state = GetCurrentState(); |
UpdateServiceState(); |
+ // Reset the polling delay. This will adjust the polling timer |
+ // based on the current service state. |
+ UpdatePollingDelay(polling_delay_seconds_); |
+ |
// Notify remote sync service state if the state has been changed. |
if (!token_->description().empty() || old_state != GetCurrentState()) { |
FOR_EACH_OBSERVER( |
@@ -732,6 +753,8 @@ |
MaybeStartFetchChanges(); |
+ SchedulePolling(); |
+ |
// Notify observer of the update of |pending_changes_|. |
FOR_EACH_OBSERVER(Observer, service_observers_, |
OnRemoteChangeQueueUpdated(pending_changes_.size())); |
@@ -1001,8 +1024,7 @@ |
metadata_store_->MoveBatchSyncOriginToIncremental(origin); |
} |
- may_have_unfetched_changes_ = true; |
- MaybeStartFetchChanges(); |
+ CheckForUpdates(); |
NotifyTaskDone(SYNC_STATUS_OK, token.Pass()); |
} |
@@ -2085,7 +2107,7 @@ |
} |
} |
-void DriveFileSyncService::OnNotificationReceived() { |
+void DriveFileSyncService::CheckForUpdates() { |
// TODO(calvinlo): Try to eliminate may_have_unfetched_changes_ variable. |
may_have_unfetched_changes_ = true; |
MaybeStartFetchChanges(); |
@@ -2175,6 +2197,15 @@ |
if (!changes->entries().empty()) |
largest_fetched_changestamp_ = changes->entries().back()->changestamp(); |
+ if (has_new_changes) { |
+ UpdatePollingDelay(kMinimumPollingDelaySeconds); |
+ } else { |
+ // If the change_queue_ was not updated, update the polling delay to wait |
+ // longer. |
+ UpdatePollingDelay(static_cast<int64>( |
+ kDelayMultiplier * polling_delay_seconds_)); |
+ } |
+ |
NotifyTaskDone(SYNC_STATUS_OK, token.Pass()); |
} |
@@ -2206,6 +2237,49 @@ |
return false; |
} |
+void DriveFileSyncService::SchedulePolling() { |
+ if (polling_timer_.IsRunning() || |
+ polling_delay_seconds_ < 0 || |
+ GetCurrentState() == REMOTE_SERVICE_DISABLED) |
+ return; |
+ |
+ DVLOG(1) << "Polling scheduled" |
+ << " (delay:" << polling_delay_seconds_ << "s)"; |
+ |
+ polling_timer_.Start( |
+ FROM_HERE, base::TimeDelta::FromSeconds(polling_delay_seconds_), |
+ base::Bind(&DriveFileSyncService::OnPollingTimerFired, AsWeakPtr())); |
+} |
+ |
+void DriveFileSyncService::OnPollingTimerFired() { |
+ may_have_unfetched_changes_ = true; |
+ MaybeStartFetchChanges(); |
+} |
+ |
+void DriveFileSyncService::UpdatePollingDelay(int64 new_delay_sec) { |
+ // polling_delay_seconds_ made negative to disable polling for testing. |
+ if (polling_delay_seconds_ < 0) |
+ return; |
+ |
+ if (state_ == REMOTE_SERVICE_TEMPORARY_UNAVAILABLE) { |
+ // If the service state is TEMPORARY_UNAVAILABLE, poll the service |
+ // with a modest duration (but more frequently than |
+ // kPollingDelaySecondsWithNotification) so that we have a mild chance |
+ // to recover the state. |
+ polling_delay_seconds_ = kMaximumPollingDelaySeconds; |
+ polling_timer_.Stop(); |
+ return; |
+ } |
+ |
+ int64 old_delay = polling_delay_seconds_; |
+ |
+ // Push notifications off. |
+ polling_delay_seconds_ = std::min(new_delay_sec, kMaximumPollingDelaySeconds); |
+ |
+ if (polling_delay_seconds_ < old_delay) |
+ polling_timer_.Stop(); |
+} |
+ |
void DriveFileSyncService::NotifyObserversFileStatusChanged( |
const FileSystemURL& url, |
SyncFileStatus sync_status, |