Bug 959130 - Stop using the SessionWorker for read at startup to avoid slowdown. r=ttaubert

This commit is contained in:
Steven MacLeod 2014-02-03 15:14:06 +01:00
parent 3559822e59
commit 61cd0fa16b
2 changed files with 56 additions and 23 deletions

View File

@ -28,6 +28,7 @@ this.EXPORTED_SYMBOLS = ["SessionFile"];
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -35,6 +36,8 @@ Cu.import("resource://gre/modules/osfile.jsm");
Cu.import("resource://gre/modules/osfile/_PromiseWorker.jsm", this);
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/AsyncShutdown.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "console",
"resource://gre/modules/devtools/Console.jsm");
@ -125,10 +128,57 @@ let SessionFileInternal = {
_isClosed: false,
read: function () {
return SessionWorker.post("read").then(msg => {
this._recordTelemetry(msg.telemetry);
return msg.ok;
// We must initialize the worker during startup so it will be ready to
// perform the final write. If shutdown happens soon after startup and
// the worker has not started yet we may not write.
// See Bug 964531.
SessionWorker.post("init");
return Task.spawn(function () {
let data = null;
for (let filename of [this.path, this.backupPath]) {
try {
data = yield this._readSessionFile(filename);
break;
} catch (ex if ex == Cr.NS_ERROR_FILE_NOT_FOUND) {
// Ignore exceptions about non-existent files.
}
}
throw new Task.Result(data || "");
}.bind(this));
},
/**
* Read the session file asynchronously.
*
* @param filename
* string The name of the session file.
* @returns {promise}
*/
_readSessionFile: function (path) {
let deferred = Promise.defer();
let file = FileUtils.File(path);
let durationMs = Date.now();
NetUtil.asyncFetch(file, function(inputStream, status) {
if (!Components.isSuccessCode(status)) {
deferred.reject(status);
return;
}
let byteLength = inputStream.available();
let data = NetUtil.readInputStreamToString(inputStream, byteLength,
{ charset: "UTF-8" });
durationMs = Date.now() - durationMs;
deferred.resolve(data);
Telemetry.getHistogramById("FX_SESSION_RESTORE_READ_FILE_MS").add(durationMs);
Telemetry.getHistogramById("FX_SESSION_RESTORE_FILE_SIZE_BYTES").add(byteLength);
});
return deferred.promise;
},
gatherTelemetry: function(aStateString) {

View File

@ -67,27 +67,10 @@ let Agent = {
backupPath: OS.Path.join(OS.Constants.Path.profileDir, "sessionstore.bak"),
/**
* Read the session from disk.
* In case sessionstore.js does not exist, attempt to read sessionstore.bak.
* NO-OP to start the worker.
*/
read: function () {
for (let path of [this.path, this.backupPath]) {
try {
let durationMs = Date.now();
let bytes = File.read(path);
durationMs = Date.now() - durationMs;
return {
result: Decoder.decode(bytes),
telemetry: {FX_SESSION_RESTORE_READ_FILE_MS: durationMs,
FX_SESSION_RESTORE_FILE_SIZE_BYTES: bytes.byteLength}
};
} catch (ex if isNoSuchFileEx(ex)) {
// Ignore exceptions about non-existent files.
}
}
// No sessionstore data files found. Return an empty string.
return {result: ""};
init: function () {
return {result: true};
},
/**