Bug 1038174 - Prevent a race condition when writing the experiments cache. r=gfritzsche, a=sledru
authorSteven MacLeod <smacleod@mozilla.com>
Thu, 24 Jul 2014 17:21:03 -0400
changeset 217647 16c940d832690f81d89e19d43b0b901f2b5ec9c2
parent 217646 a3f65bfb35a3b0ab7893dbc206cd841ae79de8e1
child 217648 36adbb8b0b8386e11d1c9df823c1a8413d1d6a2d
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgfritzsche, sledru
bugs1038174
milestone33.0a2
Bug 1038174 - Prevent a race condition when writing the experiments cache. r=gfritzsche, a=sledru We now mark the experiments cache as clean before writing the cache. This means that any changes to the data between collecting it and when the actual write executes will properly mark the cache as dirty.
browser/experiments/Experiments.jsm
--- a/browser/experiments/Experiments.jsm
+++ b/browser/experiments/Experiments.jsm
@@ -997,26 +997,34 @@ Experiments.Experiments.prototype = {
   },
 
   /*
    * Part of the main task to save the cache to disk, called from _main.
    */
   _saveToCache: function* () {
     this._log.trace("_saveToCache");
     let path = this._cacheFilePath;
-    let textData = JSON.stringify({
-      version: CACHE_VERSION,
-      data: [e[1].toJSON() for (e of this._experiments.entries())],
-    });
+    this._dirty = false;
+    try {
+      let textData = JSON.stringify({
+        version: CACHE_VERSION,
+        data: [e[1].toJSON() for (e of this._experiments.entries())],
+      });
 
-    let encoder = new TextEncoder();
-    let data = encoder.encode(textData);
-    let options = { tmpPath: path + ".tmp", compression: "lz4" };
-    yield OS.File.writeAtomic(path, data, options);
-    this._dirty = false;
+      let encoder = new TextEncoder();
+      let data = encoder.encode(textData);
+      let options = { tmpPath: path + ".tmp", compression: "lz4" };
+      yield OS.File.writeAtomic(path, data, options);
+    } catch (e) {
+      // We failed to write the cache, it's still dirty.
+      this._dirty = true;
+      this._log.error("_saveToCache failed and caught error: " + e);
+      return;
+    }
+
     this._log.debug("_saveToCache saved to " + path);
   },
 
   /*
    * Task function, load the cached experiments manifest file from disk.
    */
   _loadFromCache: Task.async(function* () {
     this._log.trace("_loadFromCache");