commit 444d77958d09ebb939addf67cbf32743cd9747db
parent 15a0f3bbe3f93074b2d5a046cec06b201c5a8543
Author: Dan Stillman <dstillman@zotero.org>
Date: Sun, 18 Jun 2017 15:37:26 -0400
Retry objects from sync queue on first sync of session and manual sync
Previously they were retried only on a backoff schedule and after a
client upgrade, but that would make it difficult to report errors
(because you'd see the error but it would then go away if you clicked
Sync again).
Diffstat:
2 files changed, 58 insertions(+), 8 deletions(-)
diff --git a/chrome/content/zotero/xpcom/sync/syncEngine.js b/chrome/content/zotero/xpcom/sync/syncEngine.js
@@ -228,15 +228,27 @@ Zotero.Sync.Data.Engine.prototype._startDownload = Zotero.Promise.coroutine(func
// Get synced settings first, since they affect how other data is displayed
let results = yield this._downloadSettings(libraryVersion);
if (results.result == this.DOWNLOAD_RESULT_LIBRARY_UNMODIFIED) {
- break;
+ let stop = true;
+ // If it's the first sync of the session or a manual sync and there are objects in the
+ // sync queue, or it's a subsequent auto-sync but there are objects that it's time to try
+ // again, go through all the steps even though the library version is unchanged.
+ //
+ // TODO: Skip the steps without queued objects.
+ if (this.firstInSession || !this.background) {
+ stop = !(yield Zotero.Sync.Data.Local.hasObjectsInSyncQueue(this.libraryID));
+ }
+ else {
+ stop = !(yield Zotero.Sync.Data.Local.hasObjectsToTryInSyncQueue(this.libraryID));
+ }
+ if (stop) {
+ break;
+ }
}
else if (results.result == this.DOWNLOAD_RESULT_RESTART) {
yield this._onLibraryVersionChange();
continue loop;
}
- else {
- newLibraryVersion = results.libraryVersion;
- }
+ newLibraryVersion = results.libraryVersion;
//
// Get other object types
@@ -319,7 +331,8 @@ Zotero.Sync.Data.Engine.prototype._downloadSettings = Zotero.Promise.coroutine(f
Zotero.debug("Library " + this.libraryID + " hasn't been modified "
+ "-- skipping further object downloads");
return {
- result: this.DOWNLOAD_RESULT_LIBRARY_UNMODIFIED
+ result: this.DOWNLOAD_RESULT_LIBRARY_UNMODIFIED,
+ libraryVersion: since
};
}
if (newLibraryVersion !== undefined && newLibraryVersion != results.libraryVersion) {
@@ -406,9 +419,20 @@ Zotero.Sync.Data.Engine.prototype._downloadUpdatedObjects = Zotero.Promise.corou
// (We don't know if the queued items are top-level or not, so we do them with child items.)
let queuedKeys = [];
if (objectType != 'item' || !options.top) {
- queuedKeys = yield Zotero.Sync.Data.Local.getObjectsToTryFromSyncQueue(
- objectType, this.libraryID
- );
+ if (this.firstInSession || !this.background) {
+ queuedKeys = yield Zotero.Sync.Data.Local.getObjectsFromSyncQueue(
+ objectType, this.libraryID
+ );
+ }
+ else {
+ queuedKeys = yield Zotero.Sync.Data.Local.getObjectsToTryFromSyncQueue(
+ objectType, this.libraryID
+ );
+ }
+ // Don't include items that just failed in the top-level run
+ if (this.failedItems.length) {
+ queuedKeys = Zotero.Utilities.arrayDiff(queuedKeys, this.failedItems);
+ }
if (queuedKeys.length) {
Zotero.debug(`Refetching ${queuedKeys.length} queued `
+ (queuedKeys.length == 1 ? objectType : objectTypePlural))
diff --git a/chrome/content/zotero/xpcom/sync/syncLocal.js b/chrome/content/zotero/xpcom/sync/syncLocal.js
@@ -1712,6 +1712,13 @@ Zotero.Sync.Data.Local = {
}),
+ hasObjectsInSyncQueue: function (libraryID) {
+ return Zotero.DB.valueQueryAsync(
+ "SELECT ROWID FROM syncQueue WHERE libraryID=? LIMIT 1", libraryID
+ ).then(x => !!x);
+ },
+
+
getObjectsFromSyncQueue: function (objectType, libraryID) {
return Zotero.DB.columnQueryAsync(
"SELECT key FROM syncQueue WHERE libraryID=? AND "
@@ -1721,6 +1728,25 @@ Zotero.Sync.Data.Local = {
},
+ hasObjectsToTryInSyncQueue: Zotero.Promise.coroutine(function* (libraryID) {
+ var rows = yield Zotero.DB.queryAsync(
+ "SELECT key, lastCheck, tries FROM syncQueue WHERE libraryID=?", libraryID
+ );
+ for (let row of rows) {
+ let interval = this._syncQueueIntervals[row.tries];
+ // Keep using last interval if beyond
+ if (!interval) {
+ interval = this._syncQueueIntervals[this._syncQueueIntervals.length - 1];
+ }
+ let nextCheck = row.lastCheck + interval * 60 * 60;
+ if (nextCheck <= Zotero.Date.getUnixTimestamp()) {
+ return true;
+ }
+ }
+ return false;
+ }),
+
+
getObjectsToTryFromSyncQueue: Zotero.Promise.coroutine(function* (objectType, libraryID) {
var syncObjectTypeID = Zotero.Sync.Data.Utilities.getSyncObjectTypeID(objectType);
var rows = yield Zotero.DB.queryAsync(