Bug 1040761 - Re-add state info for experiments async shutdown blocker from bug 1012924. r=gfritzsche

This commit is contained in:
Qeole 2014-07-25 13:40:17 +02:00
Родитель 7f41e2f894
Коммит 295a3b1ef4
1 изменённых файлов: 63 добавлений и 4 удалений

Просмотреть файл

@ -351,11 +351,28 @@ AlreadyShutdownError.prototype.constructor = AlreadyShutdownError;
*/ */
Experiments.Experiments = function (policy=new Experiments.Policy()) { Experiments.Experiments = function (policy=new Experiments.Policy()) {
this._log = Log.repository.getLoggerWithMessagePrefix( let log = Log.repository.getLoggerWithMessagePrefix(
"Browser.Experiments.Experiments", "Browser.Experiments.Experiments",
"Experiments #" + gExperimentsCounter++ + "::"); "Experiments #" + gExperimentsCounter++ + "::");
// At the time of this writing, Experiments.jsm has severe
// crashes. For forensics purposes, keep the last few log
// messages in memory and upload them in case of crash.
this._forensicsLogs = [];
this._forensicsLogs.length = 3;
this._log = Object.create(log);
this._log.log = (level, string, params) => {
this._forensicsLogs.shift();
this._forensicsLogs.push(level + ": " + string);
log.log(level, string, params);
};
this._log.trace("constructor"); this._log.trace("constructor");
// Capture the latest error, for forensics purposes.
this._latestError = null;
this._policy = policy; this._policy = policy;
// This is a Map of (string -> ExperimentEntry), keyed with the experiment id. // This is a Map of (string -> ExperimentEntry), keyed with the experiment id.
@ -405,7 +422,10 @@ Experiments.Experiments.prototype = {
gPrefsTelemetry.observe(PREF_TELEMETRY_ENABLED, this._telemetryStatusChanged, this); gPrefsTelemetry.observe(PREF_TELEMETRY_ENABLED, this._telemetryStatusChanged, this);
AddonManager.shutdown.addBlocker("Experiments.jsm shutdown", this.uninit.bind(this)); AddonManager.shutdown.addBlocker("Experiments.jsm shutdown",
this.uninit.bind(this),
this._getState.bind(this)
);
this._registerWithAddonManager(); this._registerWithAddonManager();
@ -419,6 +439,7 @@ Experiments.Experiments.prototype = {
}, },
(e) => { (e) => {
this._log.error("_loadFromCache caught error: " + e); this._log.error("_loadFromCache caught error: " + e);
this._latestError = e;
throw e; throw e;
} }
); );
@ -462,12 +483,44 @@ Experiments.Experiments.prototype = {
yield this._mainTask; yield this._mainTask;
} catch (e if e instanceof AlreadyShutdownError) { } catch (e if e instanceof AlreadyShutdownError) {
// We error out of tasks after shutdown via that exception. // We error out of tasks after shutdown via that exception.
} catch (e) {
this._latestError = e;
throw e;
} }
} }
this._log.info("Completed uninitialization."); this._log.info("Completed uninitialization.");
}), }),
// Return state information, for debugging purposes.
_getState: function() {
let state = {
isShutdown: this._shutdown,
isEnabled: gExperimentsEnabled,
isRefresh: this._refresh,
isDirty: this._dirty,
isFirstEvaluate: this._firstEvaluate,
hasLoadTask: !!this._loadTask,
hasMainTask: !!this._mainTask,
hasTimer: !!this._hasTimer,
hasAddonProvider: !!gAddonProvider,
latestLogs: this._forensicsLogs,
experiments: this._experiments.keys(),
terminateReason: this._terminateReason,
};
if (this._latestError) {
if (typeof this._latestError == "object") {
state.latestError = {
message: this._latestError.message,
stack: this._latestError.stack
};
} else {
state.latestError = "" + this._latestError;
}
}
return state;
},
_registerWithAddonManager: function (previousExperimentsProvider) { _registerWithAddonManager: function (previousExperimentsProvider) {
this._log.trace("Registering instance with Addon Manager."); this._log.trace("Registering instance with Addon Manager.");
@ -493,9 +546,15 @@ Experiments.Experiments.prototype = {
_unregisterWithAddonManager: function () { _unregisterWithAddonManager: function () {
this._log.trace("Unregistering instance with Addon Manager."); this._log.trace("Unregistering instance with Addon Manager.");
this._log.trace("Removing install listener from add-on manager.");
AddonManager.removeInstallListener(this); AddonManager.removeInstallListener(this);
this._log.trace("Removing addon listener from add-on manager.");
AddonManager.removeAddonListener(this); AddonManager.removeAddonListener(this);
this._log.trace("Finished unregistering with addon manager.");
if (gAddonProvider) { if (gAddonProvider) {
this._log.trace("Unregistering previous experiment add-on provider.");
AddonManagerPrivate.unregisterProvider(gAddonProvider); AddonManagerPrivate.unregisterProvider(gAddonProvider);
gAddonProvider = null; gAddonProvider = null;
} }