Upgrade Q, and change allResolved() to allSettled()

Not fully tested
This commit is contained in:
Dan Stillman 2013-08-16 18:15:00 -04:00
parent 81e94b4475
commit 2d7d72fb2a
4 changed files with 1089 additions and 655 deletions

View File

@ -149,7 +149,7 @@ Zotero.Sync.Storage = new function () {
else {
var promise = mode.cacheCredentials();
}
promises.push(Q.allResolved([mode, promise]));
promises.push(Q.allSettled([mode, promise]));
}
}
@ -161,12 +161,12 @@ Zotero.Sync.Storage = new function () {
// Mark WebDAV verification failure as user library error.
// We ignore credentials-caching errors for ZFS and let the
// later requests fail.
cacheCredentialsPromises.forEach(function (promise) {
let mode = promise[0].valueOf();
cacheCredentialsPromises.forEach(function (results) {
let mode = results[0].value;
if (mode == Zotero.Sync.Storage.WebDAV) {
if (promise[1].isRejected()) {
promises.push(Q.allResolved(
[0, promise[1]]
if (results[1].state == "rejected") {
promises.push(Q.allSettled(
[0, Q.reject(results[1].reason)]
));
// Skip further syncing of user library
delete libraryModes[0];
@ -179,15 +179,13 @@ Zotero.Sync.Storage = new function () {
// Get the last sync time for each library
if (self.downloadOnSync(libraryID)) {
promises.push(Q.allResolved(
promises.push(Q.allSettled(
[libraryID, libraryModes[libraryID].getLastSyncTime(libraryID)]
));
}
// If download-as-needed, we don't need the last sync time
else {
promises.push(Q.allResolved(
[libraryID, null]
));
promises.push(Q.allSettled([libraryID, null]));
}
}
return Q.all(promises);
@ -202,20 +200,17 @@ Zotero.Sync.Storage = new function () {
var libraryQueues = [];
// Get the libraries we have sync times for
promises.forEach(function (promise) {
let libraryID = promise[0].valueOf();
let lastSyncTime = promise[1].valueOf();
if (promise[1].isFulfilled()) {
promises.forEach(function (results) {
let libraryID = results[0].value;
let lastSyncTime = results[1].value;
if (results[1].state == "fulfilled") {
librarySyncTimes[libraryID] = lastSyncTime;
}
else {
let e = lastSyncTime.exception;
Zotero.debug(e);
Components.utils.reportError(e);
Zotero.debug(lastSyncTime.reason);
Components.utils.reportError(lastSyncTime.reason);
// Pass rejected promise through
libraryQueues.push(Q.allResolved(
[libraryID, lastSyncTime]
));
libraryQueues.push(results);
}
});
@ -316,7 +311,7 @@ Zotero.Sync.Storage = new function () {
// Start queues for each library
for (let libraryID in librarySyncTimes) {
libraryID = parseInt(libraryID);
libraryQueues.push(Q.allResolved(
libraryQueues.push(Q.allSettled(
[libraryID, Zotero.Sync.Storage.QueueManager.start(libraryID)]
));
}
@ -331,20 +326,20 @@ Zotero.Sync.Storage = new function () {
var changedLibraries = [];
var finalPromises = [];
promises.forEach(function (promise) {
var libraryID = promise[0].valueOf();
var libraryQueues = promise[1].valueOf();
promises.forEach(function (results) {
var libraryID = results[0].value;
var libraryQueues = results[1].value;
if (promise[1].isFulfilled()) {
if (results[1].state == "fulfilled") {
libraryQueues.forEach(function (queuePromise) {
let result = queuePromise.valueOf();
if (queuePromise.isFulfilled()) {
let result = queuePromise.inspect().value;
Zotero.debug("File " + result.type + " sync finished "
+ "for library " + libraryID);
if (result.localChanges) {
changedLibraries.push(libraryID);
}
finalPromises.push(Q.allResolved([
finalPromises.push(Q.allSettled([
libraryID,
libraryModes[libraryID].setLastSyncTime(
libraryID,
@ -353,10 +348,12 @@ Zotero.Sync.Storage = new function () {
]));
}
else {
result = result.exception;
Zotero.debug("File " + result.type + " sync failed "
let e = queuePromise.inspect().reason;
Zotero.debug("File " + e.type + " sync failed "
+ "for library " + libraryID);
finalPromises.push([libraryID, queuePromise]);
finalPromises.push(Q.allSettled(
[libraryID, Q.reject(e)]
));
}
});
}
@ -389,27 +386,26 @@ Zotero.Sync.Storage = new function () {
}
return Q.all(finalPromises)
.then(function (promises) {
var results = {
changesMade: !!changedLibraries.length,
errors: []
};
promises.forEach(function (promise) {
var libraryID = promise[0].valueOf();
if (promise[1].isRejected()) {
var result = promise[1].valueOf();
result = result.exception;
if (typeof result == 'string') {
result = new Error(result);
}
result.libraryID = libraryID;
results.errors.push(result);
.then(function (promises) {
var results = {
changesMade: !!changedLibraries.length,
errors: []
};
promises.forEach(function (promiseResults) {
var libraryID = promiseResults[0].value;
if (promiseResults[1].state == "rejected") {
let e = promiseResults[1].reason;
if (typeof e == 'string') {
e = new Error(e);
}
});
return results;
e.libraryID = libraryID;
results.errors.push(e);
}
});
return results;
});
});
}

View File

@ -53,26 +53,26 @@ Zotero.Sync.Storage.QueueManager = new function () {
Zotero.debug("No files to sync" + suffix);
}
return Q.allResolved(promises)
.then(function (promises) {
Zotero.debug("All storage queues are finished" + suffix);
promises.forEach(function (promise) {
// Check for conflicts to resolve
if (promise.isFulfilled()) {
var result = promise.valueOf();
if (result.conflicts.length) {
Zotero.debug("Reconciling conflicts for library " + result.libraryID);
Zotero.debug(result.conflicts);
var data = _reconcileConflicts(result.conflicts);
if (data) {
_processMergeData(data);
}
return Q.allSettled(promises)
.then(function (results) {
Zotero.debug("All storage queues are finished" + suffix);
results.forEach(function (result) {
// Check for conflicts to resolve
if (result.state == "fulfilled") {
result = result.value;
if (result.conflicts.length) {
Zotero.debug("Reconciling conflicts for library " + result.libraryID);
Zotero.debug(result.conflicts);
var data = _reconcileConflicts(result.conflicts);
if (data) {
_processMergeData(data);
}
}
});
return promises;
}
});
return promises;
});
};
this.stop = function (libraryID) {

View File

@ -26,7 +26,7 @@
EXPORTED_SYMBOLS = ["ConcurrentCaller"];
Components.utils.import("resource://zotero/q.js");
/**
f/**
* Call a fixed number of functions at once, queueing the rest until slots
* open and returning a promise for the final completion. The functions do
* not need to return promises, but they should if they have asynchronous
@ -79,7 +79,7 @@ ConcurrentCaller.prototype.fcall = function (func) {
//this._log("Running fcall on function");
promises.push(this.fcall(func[i]));
}
return this.stopOnError ? Q.all(promises) : Q.allResolved(promises);
return this.stopOnError ? Q.all(promises) : Q.allSettled(promises);
}
// If we're at the maximum number of concurrent functions,

File diff suppressed because it is too large Load Diff