Bug 1143796 - Increase TelemetryScheduler ticking interval when user is not active. r=gfritzsche
☠☠ backed out by f72e41028cf0 ☠ ☠
authorAlessio Placitelli <alessio.placitelli@gmail.com>
Fri, 27 Mar 2015 21:01:20 +0100
changeset 265052 f8ae18a7d017f40b1f92346a5f8f6755fc989774
parent 265051 756c80951bbbc943d01815e3236e7946f1da39e1
child 265053 208c445781e79f72d7a7a1261d03fbadda246d8b
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgfritzsche
bugs1143796
milestone39.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({