Bug 1143796 - Increase TelemetryScheduler ticking interval when user is not active. r=gfritzsche
authorAlessio Placitelli <alessio.placitelli@gmail.com>
Thu, 02 Apr 2015 21:33:46 +0200
changeset 237374 ad335ce9514040e303496f650bb347aac4b943a1
parent 237373 911d0d7068d6cfec2853829197886f120c0cc2ab
child 237375 c1a2d8973085919ad04b7ced4420204b00a043a1
push id28532
push userkwierso@gmail.com
push dateFri, 03 Apr 2015 00:18:39 +0000
treeherdermozilla-central@6177eed6d23d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgfritzsche
bugs1143796
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1143796 - Increase TelemetryScheduler ticking interval when user is not active. r=gfritzsche
toolkit/components/telemetry/TelemetrySession.jsm
--- a/toolkit/components/telemetry/TelemetrySession.jsm
+++ b/toolkit/components/telemetry/TelemetrySession.jsm
@@ -81,16 +81,18 @@ const MAX_NUM_CONTENT_PAYLOADS = 10;
 // 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;
 // Execute a scheduler tick every 5 minutes.
 const SCHEDULER_TICK_INTERVAL_MS = 5 * 60 * 1000;
+// When user is idle, execute a scheduler tick every 60 minutes.
+const SCHEDULER_TICK_IDLE_INTERVAL_MS = 60 * 60 * 1000;
 // The maximum number of times a scheduled operation can fail.
 const SCHEDULER_RETRY_ATTEMPTS = 3;
 
 // The tolerance we have when checking if it's midnight (15 minutes).
 const SCHEDULER_MIDNIGHT_TOLERANCE_MS = 15 * 60 * 1000;
 
 // Coalesce the daily and aborted-session pings if they are both due within
 // two minutes from each other.
@@ -411,49 +413,53 @@ let TelemetryScheduler = {
 
   _log: null,
 
   // The number of times a daily ping fails.
   _dailyPingRetryAttempts: 0,
 
   // The timer which drives the scheduler.
   _schedulerTimer: null,
+  // The interval used by the scheduler timer.
+  _schedulerInterval: 0,
   _shuttingDown: true,
 
   /**
    * Initialises the scheduler and schedules the first daily/aborted session pings.
    */
   init: function() {
     this._log = Log.repository.getLoggerWithMessagePrefix(LOGGER_NAME, "TelemetryScheduler::");
     this._log.trace("init");
     this._shuttingDown = false;
     // Initialize the last daily ping and aborted session last due times to the current time.
     // Otherwise, we might end up sending daily pings even if the subsession is not long enough.
     let now = Policy.now();
     this._lastDailyPingTime = now.getTime();
     this._lastSessionCheckpointTime = now.getTime();
+    this._schedulerInterval = SCHEDULER_TICK_INTERVAL_MS;
     this._rescheduleTimeout();
+    idleService.addIdleObserver(this, IDLE_TIMEOUT_SECONDS);
   },
 
   /**
    * Reschedules the tick timer.
    */
   _rescheduleTimeout: function() {
-    this._log.trace("_rescheduleTimeout");
+    this._log.trace("_rescheduleTimeout - timeout: " + this._schedulerInterval);
     if (this._shuttingDown) {
       this._log.warn("_rescheduleTimeout - already shutdown");
       return;
     }
 
     if (this._schedulerTimer) {
       Policy.clearSchedulerTickTimeout(this._schedulerTimer);
     }
 
     this._schedulerTimer =
-      Policy.setSchedulerTickTimeout(() => this._onSchedulerTick(), SCHEDULER_TICK_INTERVAL_MS);
+      Policy.setSchedulerTickTimeout(() => this._onSchedulerTick(), this._schedulerInterval);
   },
 
   /**
    * Checks if we can send a daily ping or not.
    * @param {Object} nowDate A date object.
    * @return {Boolean} True if we can send the daily ping, false otherwise.
    */
   _isDailyPingDue: function(nowDate) {
@@ -494,16 +500,35 @@ let TelemetryScheduler = {
    */
   _saveAbortedPing: function(now, competingPayload=null) {
     this._lastSessionCheckpointTime = now;
     return Impl._saveAbortedSessionPing(competingPayload)
                 .catch(e => this._log.error("_saveAbortedPing - Failed", e));
   },
 
   /**
+   * The notifications handler.
+   */
+  observe: function(aSubject, aTopic, aData) {
+    this._log.trace("observe - aTopic: " + aTopic);
+    switch(aTopic) {
+      case "idle":
+        // If the user is idle, increase the tick interval.
+        this._schedulerInterval = SCHEDULER_TICK_IDLE_INTERVAL_MS;
+        this._rescheduleTimeout();
+        break;
+      case "active":
+        // User is back to work, restore the original tick interval.
+        this._schedulerInterval = SCHEDULER_TICK_INTERVAL_MS;
+        this._rescheduleTimeout();
+        break;
+    }
+  },
+
+  /**
    * Performs a scheduler tick. This function manages Telemetry recurring operations.
    * @return {Promise} A promise, only used when testing, resolved when the scheduled
    *                   operation completes.
    */
   _onSchedulerTick: function() {
     if (this._shuttingDown) {
       this._log.warn("_onSchedulerTick - already shutdown.");
       return;
@@ -645,16 +670,18 @@ let TelemetryScheduler = {
     }
 
     this._log.trace("shutdown");
     if (this._schedulerTimer) {
       Policy.clearSchedulerTickTimeout(this._schedulerTimer);
       this._schedulerTimer = null;
     }
 
+    idleService.removeIdleObserver(this, IDLE_TIMEOUT_SECONDS);
+
     this._shuttingDown = true;
   }
 };
 
 this.EXPORTED_SYMBOLS = ["TelemetrySession"];
 
 this.TelemetrySession = Object.freeze({
   Constants: Object.freeze({