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).
This commit is contained in:
Dan Stillman 2017-06-18 15:37:26 -04:00
parent 15a0f3bbe3
commit 444d77958d
2 changed files with 58 additions and 8 deletions

View file

@ -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))

View file

@ -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(