Bug 1052545 - Telemetry experiment branches are not saved correctly: we set the _dirty flag correctly, but then don't write the cache, r=gfritzsche

--HG--
extra : rebase_source : 8b531590cb76292b39c83d3928fc0107f1e83424
This commit is contained in:
Benjamin Smedberg 2014-08-14 16:21:15 -04:00
parent 85a96cac1c
commit 1b91a46df9

View File

@ -64,6 +64,8 @@ const PREF_TELEMETRY_ENABLED = "enabled";
const URI_EXTENSION_STRINGS = "chrome://mozapps/locale/extensions/extensions.properties";
const STRING_TYPE_NAME = "type.%ID%.name";
const CACHE_WRITE_RETRY_DELAY_SEC = 60 * 3;
const TELEMETRY_LOG = {
// log(key, [kind, experimentId, details])
ACTIVATION_KEY: "EXPERIMENT_ACTIVATION",
@ -331,10 +333,19 @@ function AlreadyShutdownError(message="already shut down") {
this.message = message;
this.stack = error.stack;
}
AlreadyShutdownError.prototype = Object.create(Error.prototype);
AlreadyShutdownError.prototype.constructor = AlreadyShutdownError;
function CacheWriteError(message="Error writing cache file") {
Error.call(this, message);
let error = new Error();
this.name = "CacheWriteError";
this.message = message;
this.stack = error.stack;
}
CacheWriteError.prototype = Object.create(Error.prototype);
CacheWriteError.prototype.constructor = CacheWriteError;
/**
* Manages the experiments and provides an interface to control them.
*/
@ -690,6 +701,7 @@ Experiments.Experiments.prototype = {
throw new Error("Experiment not found");
}
e.branch = String(branchstr);
this._log.trace("setExperimentBranch(" + id + ", " + e.branch + ") _dirty=" + this._dirty);
this._dirty = true;
Services.obs.notifyObservers(null, EXPERIMENTS_CHANGED_TOPIC, null);
yield this._run();
@ -766,6 +778,8 @@ Experiments.Experiments.prototype = {
this._mainTask = Task.spawn(function*() {
try {
yield this._main();
} catch (e if e instanceof CacheWriteError) {
// In this case we want to reschedule
} catch (e) {
this._log.error("_main caught error: " + e);
return;
@ -801,7 +815,7 @@ Experiments.Experiments.prototype = {
// If somebody called .updateManifest() or disableExperiment()
// while we were running, go again right now.
}
while (this._refresh || this._terminateReason);
while (this._refresh || this._terminateReason || this._dirty);
},
_loadManifest: function*() {
@ -992,7 +1006,7 @@ Experiments.Experiments.prototype = {
// We failed to write the cache, it's still dirty.
this._dirty = true;
this._log.error("_saveToCache failed and caught error: " + e);
return;
throw new CacheWriteError();
}
this._log.debug("_saveToCache saved to " + path);
@ -1307,6 +1321,10 @@ Experiments.Experiments.prototype = {
let time = null;
let now = this._policy.now().getTime();
if (this._dirty) {
// If we failed to write the cache, we should try again periodically
time = now + 1000 * CACHE_WRITE_RETRY_DELAY_SEC;
}
for (let [id, experiment] of this._experiments) {
let scheduleTime = experiment.getScheduleTime();