Bug 1101487 - Cache client id in prefs so we can submit it for very short sessions too. r=vladan
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Wed, 17 Dec 2014 17:45:58 +0100
changeset 220210 3a105575e0da5af97664769a4fb5bd9f4fbfdf8a
parent 220209 8d40b95ffdbfa357790e81ee4dc39b67b506576e
child 220211 95e2754cb8e7824a4b9b84184b5fc7af9d10e61d
push id10457
push userryanvm@gmail.com
push dateThu, 18 Dec 2014 01:54:25 +0000
treeherderfx-team@0e441ff66c5e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvladan
bugs1101487
milestone37.0a1
Bug 1101487 - Cache client id in prefs so we can submit it for very short sessions too. r=vladan
toolkit/components/telemetry/TelemetryPing.jsm
toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
--- a/toolkit/components/telemetry/TelemetryPing.jsm
+++ b/toolkit/components/telemetry/TelemetryPing.jsm
@@ -15,28 +15,30 @@ Cu.import("resource://gre/modules/Servic
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 #ifndef MOZ_WIDGET_GONK
 Cu.import("resource://gre/modules/LightweightThemeManager.jsm", this);
 #endif
 Cu.import("resource://gre/modules/ThirdPartyCookieProbe.jsm", this);
 Cu.import("resource://gre/modules/Promise.jsm", this);
 Cu.import("resource://gre/modules/Task.jsm", this);
 Cu.import("resource://gre/modules/AsyncShutdown.jsm", this);
+Cu.import("resource://gre/modules/Preferences.jsm");
 
 // When modifying the payload in incompatible ways, please bump this version number
 const PAYLOAD_VERSION = 1;
 
 // This is the HG changeset of the Histogram.json file, used to associate
 // submitted ping data with its histogram definition (bug 832007)
 #expand const HISTOGRAMS_FILE_VERSION = "__HISTOGRAMS_FILE_VERSION__";
 
 const PREF_BRANCH = "toolkit.telemetry.";
 const PREF_SERVER = PREF_BRANCH + "server";
 const PREF_ENABLED = PREF_BRANCH + "enabled";
 const PREF_PREVIOUS_BUILDID = PREF_BRANCH + "previousBuildID";
+const PREF_CACHED_CLIENTID = PREF_BRANCH + "cachedClientID"
 const PREF_FHR_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
 
 // Do not gather data more than once a minute
 const TELEMETRY_INTERVAL = 60000;
 // Delay before intializing telemetry (ms)
 const TELEMETRY_DELAY = 60000;
 // Delay before initializing telemetry if we're testing (ms)
 const TELEMETRY_TEST_DELAY = 100;
@@ -950,16 +952,22 @@ let Impl = {
     }
     if (!enabled) {
       // Turn off local telemetry if telemetry is disabled.
       // This may change once about:telemetry is added.
       Telemetry.canRecord = false;
       return;
     }
 
+    // For very short session durations, we may never load the client
+    // id from disk.
+    // We try to cache it in prefs to avoid this, even though this may
+    // lead to some stale client ids.
+    this._clientID = Preferences.get(PREF_CACHED_CLIENTID, null);
+
     AsyncShutdown.sendTelemetry.addBlocker(
       "Telemetry: shutting down",
       function condition(){
         this.uninstall();
         if (Telemetry.canSend) {
           return this.savePendingPings();
         }
       }.bind(this));
@@ -993,16 +1001,21 @@ let Impl = {
           yield this.send("overdue-flush", this._server);
         }
 
         if ("@mozilla.org/datareporting/service;1" in Cc) {
           let drs = Cc["@mozilla.org/datareporting/service;1"]
                       .getService(Ci.nsISupports)
                       .wrappedJSObject;
           this._clientID = yield drs.getClientID();
+          // Update cached client id.
+          Preferences.set(PREF_CACHED_CLIENTID, this._clientID);
+        } else {
+          // Nuke potentially cached client id.
+          Preferences.reset(PREF_CACHED_CLIENTID);
         }
 
         this.attachObservers();
         this.gatherMemory();
 
         Telemetry.asyncFetchTelemetryData(function () {});
         delete this._timer;
         deferred.resolve();
@@ -1053,16 +1066,17 @@ let Impl = {
     if (this._hasXulWindowVisibleObserver) {
       Services.obs.removeObserver(this, "xul-window-visible");
       this._hasXulWindowVisibleObserver = false;
     }
     Services.obs.removeObserver(this, "quit-application-granted");
 #ifdef MOZ_WIDGET_ANDROID
     Services.obs.removeObserver(this, "application-background", false);
 #endif
+    this._clientID = null;
   },
 
   getPayload: function getPayload() {
     // This function returns the current Telemetry payload to the caller.
     // We only gather startup info once.
     if (Object.keys(this._slowSQLStartup).length == 0) {
       this.gatherStartupHistograms();
       this._slowSQLStartup = Telemetry.slowSQL;
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
@@ -16,16 +16,17 @@ const Cr = Components.results;
 Cu.import("resource://testing-common/httpd.js", this);
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/LightweightThemeManager.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/TelemetryPing.jsm", this);
 Cu.import("resource://gre/modules/TelemetryFile.jsm", this);
 Cu.import("resource://gre/modules/Task.jsm", this);
 Cu.import("resource://gre/modules/Promise.jsm", this);
+Cu.import("resource://gre/modules/Preferences.jsm");
 
 const IGNORE_HISTOGRAM = "test::ignore_me";
 const IGNORE_HISTOGRAM_TO_CLONE = "MEMORY_HEAP_ALLOCATED";
 const IGNORE_CLONED_HISTOGRAM = "test::ignore_me_also";
 const ADDON_NAME = "Telemetry test addon";
 const ADDON_HISTOGRAM = "addon-histogram";
 // Add some unicode characters here to ensure that sending them works correctly.
 const FLASH_VERSION = "\u201c1.1.1.1\u201d";
@@ -491,16 +492,22 @@ function actualTest() {
   run_next_test();
 }
 
 add_task(function* asyncSetup() {
   yield TelemetryPing.setup();
 
   if ("@mozilla.org/datareporting/service;1" in Cc) {
     gDataReportingClientID = yield gDatareportingService.getClientID();
+
+    // We should have cached the client id now. Lets confirm that by
+    // checking the client id before the async ping setup is finished.
+    let promisePingSetup = TelemetryPing.reset();
+    do_check_eq(TelemetryPing.clientID, gDataReportingClientID);
+    yield promisePingSetup;
   }
 });
 
 // Ensure that not overwriting an existing file fails silently
 add_task(function* test_overwritePing() {
   let ping = {slug: "foo"}
   yield TelemetryFile.savePing(ping, true);
   yield TelemetryFile.savePing(ping, false);