зеркало из https://github.com/mozilla/gecko-dev.git
Tweak logging output; make detectUpdates asynchronous (makes the spinny much smoother); avoid setting timers in our service object; add missing piece to support query items; force cache verification when making requests (to avoid using stale data)
This commit is contained in:
Родитель
f4e685b35c
Коммит
cd969651d8
|
@ -126,9 +126,6 @@ BookmarksSyncService.prototype = {
|
|||
// Logger object
|
||||
_log: null,
|
||||
|
||||
// Timer object for yielding to the main loop
|
||||
_timer: null,
|
||||
|
||||
// Timer object for automagically syncing
|
||||
_scheduleTimer: null,
|
||||
|
||||
|
@ -224,14 +221,14 @@ BookmarksSyncService.prototype = {
|
|||
|
||||
let formatter = logSvc.newFormatter("basic");
|
||||
let root = logSvc.rootLogger;
|
||||
root.level = root.LEVEL_ALL;
|
||||
root.level = root.LEVEL_DEBUG;
|
||||
|
||||
let capp = logSvc.newAppender("console", formatter);
|
||||
capp.level = root.LEVEL_WARN;
|
||||
root.addAppender(capp);
|
||||
|
||||
let dapp = logSvc.newAppender("dump", formatter);
|
||||
dapp.level = root.LEVEL_WARN;
|
||||
dapp.level = root.LEVEL_ALL;
|
||||
root.addAppender(dapp);
|
||||
|
||||
let dirSvc = Cc["@mozilla.org/file/directory_service;1"].
|
||||
|
@ -247,7 +244,7 @@ BookmarksSyncService.prototype = {
|
|||
fapp.level = root.LEVEL_INFO;
|
||||
root.addAppender(fapp);
|
||||
let vapp = logSvc.newFileAppender("rotating", verboseFile, formatter);
|
||||
vapp.level = root.LEVEL_ALL;
|
||||
vapp.level = root.LEVEL_DEBUG;
|
||||
root.addAppender(vapp);
|
||||
},
|
||||
|
||||
|
@ -392,45 +389,69 @@ BookmarksSyncService.prototype = {
|
|||
return this._nodeParentsInt(tree[GUID].parentGUID, tree, parents);
|
||||
},
|
||||
|
||||
_detectUpdates: function BSS__detectUpdates(a, b) {
|
||||
_detectUpdates: function BSS__detectUpdates(onComplete, a, b) {
|
||||
let cont = yield;
|
||||
let listener = new EventListener(cont);
|
||||
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
|
||||
let cmds = [];
|
||||
for (let GUID in a) {
|
||||
if (GUID in b) {
|
||||
let edits = this._getEdits(a[GUID], b[GUID]);
|
||||
if (edits == -1) // something went very wrong -- FIXME
|
||||
continue;
|
||||
if (edits.numProps == 0) // no changes - skip
|
||||
|
||||
try {
|
||||
for (let GUID in a) {
|
||||
|
||||
timer.initWithCallback(listener, 0, timer.TYPE_ONE_SHOT);
|
||||
yield; // Yield to main loop
|
||||
|
||||
if (GUID in b) {
|
||||
let edits = this._getEdits(a[GUID], b[GUID]);
|
||||
if (edits == -1) // something went very wrong -- FIXME
|
||||
continue;
|
||||
if (edits.numProps == 0) // no changes - skip
|
||||
continue;
|
||||
let parents = this._nodeParents(GUID, b);
|
||||
cmds.push({action: "edit", GUID: GUID,
|
||||
depth: parents.length, parents: parents,
|
||||
data: edits.props});
|
||||
} else {
|
||||
let parents = this._nodeParents(GUID, a); // ???
|
||||
cmds.push({action: "remove", GUID: GUID,
|
||||
depth: parents.length, parents: parents});
|
||||
}
|
||||
}
|
||||
for (let GUID in b) {
|
||||
|
||||
timer.initWithCallback(listener, 0, timer.TYPE_ONE_SHOT);
|
||||
yield; // Yield to main loop
|
||||
|
||||
if (GUID in a)
|
||||
continue;
|
||||
let parents = this._nodeParents(GUID, b);
|
||||
cmds.push({action: "edit", GUID: GUID,
|
||||
cmds.push({action: "create", GUID: GUID,
|
||||
depth: parents.length, parents: parents,
|
||||
data: edits.props});
|
||||
} else {
|
||||
let parents = this._nodeParents(GUID, a); // ???
|
||||
cmds.push({action: "remove", GUID: GUID,
|
||||
depth: parents.length, parents: parents});
|
||||
data: b[GUID]});
|
||||
}
|
||||
cmds.sort(function(a, b) {
|
||||
if (a.depth > b.depth)
|
||||
return 1;
|
||||
if (a.depth < b.depth)
|
||||
return -1;
|
||||
if (a.index > b.index)
|
||||
return -1;
|
||||
if (a.index < b.index)
|
||||
return 1;
|
||||
return 0; // should never happen, but not a big deal if it does
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
if (e != 'close generator')
|
||||
this._log.error("Exception caught: " + e.message);
|
||||
|
||||
} finally {
|
||||
timer = null;
|
||||
generatorDone(this, onComplete, cmds);
|
||||
yield; // onComplete is responsible for closing the generator
|
||||
}
|
||||
for (let GUID in b) {
|
||||
if (GUID in a)
|
||||
continue;
|
||||
let parents = this._nodeParents(GUID, b);
|
||||
cmds.push({action: "create", GUID: GUID,
|
||||
depth: parents.length, parents: parents,
|
||||
data: b[GUID]});
|
||||
}
|
||||
cmds.sort(function(a, b) {
|
||||
if (a.depth > b.depth)
|
||||
return 1;
|
||||
if (a.depth < b.depth)
|
||||
return -1;
|
||||
if (a.index > b.index)
|
||||
return -1;
|
||||
if (a.index < b.index)
|
||||
return 1;
|
||||
return 0; // should never happen, but not a big deal if it does
|
||||
});
|
||||
return cmds;
|
||||
this._log.warn("generator not properly closed");
|
||||
},
|
||||
|
||||
// Bookmarks are allowed to be in a different index as long as they
|
||||
|
@ -463,6 +484,11 @@ BookmarksSyncService.prototype = {
|
|||
a.data.title == b.data.title)
|
||||
return true;
|
||||
return false;
|
||||
case "query":
|
||||
if (a.data.URI == b.data.URI &&
|
||||
a.data.title == b.data.title)
|
||||
return true;
|
||||
return false;
|
||||
case "microsummary":
|
||||
if (a.data.URI == b.data.URI &&
|
||||
a.data.generatorURI == b.data.generatorURI)
|
||||
|
@ -549,20 +575,21 @@ BookmarksSyncService.prototype = {
|
|||
},
|
||||
|
||||
_reconcile: function BSS__reconcile(onComplete, listA, listB) {
|
||||
let cont = yield;
|
||||
let listener = new EventListener(cont);
|
||||
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
|
||||
let propagations = [[], []];
|
||||
let conflicts = [[], []];
|
||||
let ret = {propagations: propagations, conflicts: conflicts};
|
||||
|
||||
try {
|
||||
let cont = yield;
|
||||
let listener = new EventListener(cont);
|
||||
this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
|
||||
for (let i = 0; i < listA.length; i++) {
|
||||
this._timer.initWithCallback(listener, 0, this._timer.TYPE_ONE_SHOT);
|
||||
yield; // Yield to main loop
|
||||
|
||||
for (let j = 0; j < listB.length; j++) {
|
||||
|
||||
timer.initWithCallback(listener, 0, timer.TYPE_ONE_SHOT);
|
||||
yield; // Yield to main loop
|
||||
|
||||
if (this._deepEquals(listA[i], listB[j])) {
|
||||
delete listA[i];
|
||||
delete listB[j];
|
||||
|
@ -588,10 +615,11 @@ BookmarksSyncService.prototype = {
|
|||
listB = listB.filter(function(elt) { return elt });
|
||||
|
||||
for (let i = 0; i < listA.length; i++) {
|
||||
this._timer.initWithCallback(listener, 0, this._timer.TYPE_ONE_SHOT);
|
||||
yield; // Yield to main loop
|
||||
|
||||
for (let j = 0; j < listB.length; j++) {
|
||||
|
||||
timer.initWithCallback(listener, 0, timer.TYPE_ONE_SHOT);
|
||||
yield; // Yield to main loop
|
||||
|
||||
if (this._conflicts(listA[i], listB[j]) ||
|
||||
this._conflicts(listB[j], listA[i])) {
|
||||
if (!conflicts[0].some(
|
||||
|
@ -606,7 +634,7 @@ BookmarksSyncService.prototype = {
|
|||
|
||||
this._getPropagations(listA, conflicts[0], propagations[1]);
|
||||
|
||||
this._timer.initWithCallback(listener, 0, this._timer.TYPE_ONE_SHOT);
|
||||
timer.initWithCallback(listener, 0, timer.TYPE_ONE_SHOT);
|
||||
yield; // Yield to main loop
|
||||
|
||||
this._getPropagations(listB, conflicts[1], propagations[0]);
|
||||
|
@ -617,7 +645,7 @@ BookmarksSyncService.prototype = {
|
|||
this._log.error("Exception caught: " + e.message);
|
||||
|
||||
} finally {
|
||||
this._timer = null;
|
||||
timer = null;
|
||||
generatorDone(this, onComplete, ret);
|
||||
yield; // onComplete is responsible for closing the generator
|
||||
}
|
||||
|
@ -946,7 +974,10 @@ BookmarksSyncService.prototype = {
|
|||
// 2) Generate local deltas from snapshot -> current client status
|
||||
|
||||
let localJson = this._getBookmarks();
|
||||
let localUpdates = this._detectUpdates(this._snapshot, localJson);
|
||||
gen = this._detectUpdates.async(this, cont, this._snapshot, localJson);
|
||||
let localUpdates = yield;
|
||||
gen.close();
|
||||
|
||||
this._log.debug("local json:\n" + this._mungeNodes(localJson));
|
||||
this._log.debug("Local updates: " + this._mungeCommands(localUpdates));
|
||||
this._log.debug("Server updates: " + this._mungeCommands(server.updates));
|
||||
|
@ -1008,9 +1039,11 @@ BookmarksSyncService.prototype = {
|
|||
this._applyCommands(clientChanges);
|
||||
newSnapshot = this._getBookmarks();
|
||||
|
||||
let diff = this._detectUpdates(this._snapshot, newSnapshot);
|
||||
gen = this._detectUpdates.async(this, cont, this._snapshot, newSnapshot);
|
||||
let diff = yield;
|
||||
gen.close();
|
||||
if (diff.length != 0) {
|
||||
this._log.error("Commands did not apply correctly");
|
||||
this._log.warn("Commands did not apply correctly");
|
||||
this._log.debug("Diff from snapshot+commands -> " +
|
||||
"new snapshot after commands:\n" +
|
||||
this._mungeCommands(diff));
|
||||
|
@ -1029,7 +1062,9 @@ BookmarksSyncService.prototype = {
|
|||
// conflicts, it should be the same as what the resolver returned
|
||||
|
||||
newSnapshot = this._getBookmarks();
|
||||
let serverDelta = this._detectUpdates(server.snapshot, newSnapshot);
|
||||
gen = this._detectUpdates.async(this, cont, server.snapshot, newSnapshot);
|
||||
let serverDelta = yield;
|
||||
gen.close();
|
||||
|
||||
// Log an error if not the same
|
||||
if (!(serverConflicts.length ||
|
||||
|
@ -1267,7 +1302,9 @@ BookmarksSyncService.prototype = {
|
|||
ret.snapVersion = status.snapVersion;
|
||||
ret.snapshot = snap;
|
||||
ret.deltas = allDeltas;
|
||||
ret.updates = this._detectUpdates(this._snapshot, snap);
|
||||
gen = this._detectUpdates.async(this, cont, this._snapshot, snap);
|
||||
ret.updates = yield;
|
||||
gen.close();
|
||||
break;
|
||||
|
||||
case 404:
|
||||
|
@ -1761,7 +1798,15 @@ DAVCollection.prototype = {
|
|||
request.addEventListener("error", new EventListener(cont, "error"), false);
|
||||
request = request.QueryInterface(Ci.nsIXMLHttpRequest);
|
||||
request.open(op, this._userURL + path, true);
|
||||
|
||||
|
||||
|
||||
// Force cache validation
|
||||
let channel = request.channel;
|
||||
channel = channel.QueryInterface(Ci.nsIRequest);
|
||||
let loadFlags = channel.loadFlags;
|
||||
loadFlags |= Ci.nsIRequest.VALIDATE_ALWAYS;
|
||||
channel.loadFlags = loadFlags;
|
||||
|
||||
let key;
|
||||
for (key in headers) {
|
||||
this._log.debug("HTTP Header " + key + ": " + headers[key]);
|
||||
|
|
Загрузка…
Ссылка в новой задаче