Bug 988301 - Avoid main-thread IO in Sync code. r=Yoric, r=rnewman

This commit is contained in:
Marco Castelluccio 2014-04-07 10:49:32 -04:00
parent 047732cf2f
commit e07ebcf402
4 changed files with 41 additions and 48 deletions

View File

@ -13,6 +13,8 @@ Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/engines.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Status",
"resource://services-sync/status.js");

View File

@ -2,8 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
this.EXPORTED_SYMBOLS = ["XPCOMUtils", "Services", "NetUtil",
"FileUtils", "Utils", "Async", "Svc", "Str"];
this.EXPORTED_SYMBOLS = ["XPCOMUtils", "Services", "Utils", "Async", "Svc", "Str"];
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
@ -14,11 +13,11 @@ Cu.import("resource://services-common/utils.js");
Cu.import("resource://services-common/async.js", this);
Cu.import("resource://services-crypto/utils.js");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://gre/modules/FileUtils.jsm", this);
Cu.import("resource://gre/modules/NetUtil.jsm", this);
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/Services.jsm", this);
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
Cu.import("resource://gre/modules/osfile.jsm", this);
Cu.import("resource://gre/modules/Task.jsm", this);
/*
* Utility functions
@ -337,41 +336,28 @@ this.Utils = {
* Function to process json object as its first argument. If the file
* could not be loaded, the first argument will be undefined.
*/
jsonLoad: function jsonLoad(filePath, that, callback) {
let path = "weave/" + filePath + ".json";
jsonLoad: Task.async(function*(filePath, that, callback) {
let path = OS.Path.join(OS.Constants.Path.profileDir, "weave", filePath + ".json");
if (that._log) {
that._log.trace("Loading json from disk: " + filePath);
}
let file = FileUtils.getFile("ProfD", path.split("/"), true);
if (!file.exists()) {
callback.call(that);
return;
let json;
try {
json = yield CommonUtils.readJSON(path);
} catch (e if e instanceof OS.File.Error && e.becauseNoSuchFile) {
// Ignore non-existent files.
} catch (e) {
if (that._log) {
that._log.debug("Failed to load json: " +
CommonUtils.exceptionStr(e));
}
}
let channel = NetUtil.newChannel(file);
channel.contentType = "application/json";
NetUtil.asyncFetch(channel, function (is, result) {
if (!Components.isSuccessCode(result)) {
callback.call(that);
return;
}
let string = NetUtil.readInputStreamToString(is, is.available());
is.close();
let json;
try {
json = JSON.parse(string);
} catch (ex) {
if (that._log) {
that._log.debug("Failed to load json: " +
CommonUtils.exceptionStr(ex));
}
}
callback.call(that, json);
});
},
callback.call(that, json);
}),
/**
* Save a json-able object to disk in the profile directory.
@ -389,25 +375,27 @@ this.Utils = {
* constant on error or null if no error was encountered (and
* the file saved successfully).
*/
jsonSave: function jsonSave(filePath, that, obj, callback) {
let path = "weave/" + filePath + ".json";
if (that._log) {
that._log.trace("Saving json to disk: " + path);
}
jsonSave: Task.async(function*(filePath, that, obj, callback) {
let path = OS.Path.join(OS.Constants.Path.profileDir, "weave",
...(filePath + ".json").split("/"));
let dir = OS.Path.dirname(path);
let error = null;
let file = FileUtils.getFile("ProfD", path.split("/"), true);
let json = typeof obj == "function" ? obj.call(that) : obj;
let out = JSON.stringify(json);
try {
yield OS.File.makeDir(dir, { from: OS.Constants.Path.profileDir });
let fos = FileUtils.openSafeFileOutputStream(file);
let is = this._utf8Converter.convertToInputStream(out);
NetUtil.asyncCopy(is, fos, function (result) {
if (typeof callback == "function") {
let error = (result == Cr.NS_OK) ? null : result;
callback.call(that, error);
if (that._log) {
that._log.trace("Saving json to disk: " + path);
}
});
},
let json = typeof obj == "function" ? obj.call(that) : obj;
yield CommonUtils.writeJSON(json, path);
} catch (e) {
error = e
}
callback.call(that, error);
}),
getErrorString: function Utils_getErrorString(error, args) {
try {

View File

@ -10,6 +10,7 @@ Cu.import("resource://services-sync/service.js");
Cu.import("resource://services-sync/status.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://testing-common/services/sync/utils.js");
Cu.import("resource://gre/modules/FileUtils.jsm");
const FAKE_SERVER_URL = "http://dummy:9000/";
const logsdir = FileUtils.getDir("ProfD", ["weave", "logs"], true);

View File

@ -5,6 +5,8 @@ Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js");
Cu.import("resource://services-sync/service.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
const logsdir = FileUtils.getDir("ProfD", ["weave", "logs"], true);
const LOG_PREFIX_SUCCESS = "success-";