Bug 1100863 - SimplePush: Adaptive ping doesn't work when it converge. f=jorgep, r=nsm
authorFernando Rodriguez Sela <frsela@tid.es>
Mon, 16 Feb 2015 01:00:00 -0500
changeset 257106 eb836d0e41ff38f41af1585fc3c0fed85ef3faab
parent 257105 9ca878db19bead9376ede11572c1d0d8755fca0b
child 257107 a1463070ce7162fe452fb5e32ae27d2baac2f36a
push id4610
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:32:55 +0000
treeherdermozilla-beta@4df54044d9ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnsm
bugs1100863
milestone38.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 1100863 - SimplePush: Adaptive ping doesn't work when it converge. f=jorgep, r=nsm
dom/push/PushService.jsm
--- a/dom/push/PushService.jsm
+++ b/dom/push/PushService.jsm
@@ -47,30 +47,32 @@ const kPUSHDB_STORE_NAME = "push";
 
 const kUDP_WAKEUP_WS_STATUS_CODE = 4774;  // WebSocket Close status code sent
                                           // by server to signal that it can
                                           // wake client up using UDP.
 
 const kCHILD_PROCESS_MESSAGES = ["Push:Register", "Push:Unregister",
                                  "Push:Registrations"];
 
+const kWS_MAX_WENTDOWN = 2;
+
 // This is a singleton
 this.PushDB = function PushDB() {
   debug("PushDB()");
 
   // set the indexeddb database
   this.initDBHelper(kPUSHDB_DB_NAME, kPUSHDB_DB_VERSION,
                     [kPUSHDB_STORE_NAME]);
 };
 
 this.PushDB.prototype = {
   __proto__: IndexedDBHelper.prototype,
 
   upgradeSchema: function(aTransaction, aDb, aOldVersion, aNewVersion) {
-    debug("PushDB.upgradeSchema()")
+    debug("PushDB.upgradeSchema()");
 
     let objectStore = aDb.createObjectStore(kPUSHDB_STORE_NAME,
                                             { keyPath: "channelID" });
 
     // index to fetch records based on endpoints. used by unregister
     objectStore.createIndex("pushEndpoint", "pushEndpoint", { unique: true });
 
     // index to fetch records per manifest, so we can identify endpoints
@@ -477,16 +479,22 @@ this.PushService = {
   _lastGoodPingInterval: 0,
 
   /**
    * Maximum ping interval that we can reach.
    */
   _upperLimit: 0,
 
   /**
+   * Count the times WebSocket goes down without receiving Pings
+   * so we can re-enable the ping recalculation algorithm
+   */
+  _wsWentDownCounter: 0,
+
+  /**
    * Sends a message to the Push Server through an open websocket.
    * typeof(msg) shall be an object
    */
   _wsSendMessage: function(msg) {
     if (!this._ws) {
       debug("No WebSocket initialized. Cannot send a message.");
       return;
     }
@@ -673,16 +681,21 @@ this.PushService = {
 
     if (this._retryFailCount > 0) {
       debug('Push has failed to connect to the Push Server ' +
         this._retryFailCount + ' times. ' +
         'Do not calculate a new pingInterval now');
       return;
     }
 
+    if (!wsWentDown) {
+      debug('Setting websocket down counter to 0');
+      this._wsWentDownCounter = 0;
+    }
+
     if (!this._recalculatePing && !wsWentDown) {
       debug('We do not need to recalculate the ping now, based on previous data');
       return;
     }
 
     // Save actual state of the network
     let ns = this._getNetworkInformation();
 
@@ -717,16 +730,34 @@ this.PushService = {
       // wifi
       debug('wifi');
       prefs.set('pingInterval', prefs.get('pingInterval.wifi'));
       this._lastGoodPingInterval = prefs.get('adaptive.lastGoodPingInterval.wifi');
     }
 
     let nextPingInterval;
     let lastTriedPingInterval = prefs.get('pingInterval');
+
+    if (!this._recalculatePing && wsWentDown) {
+      debug('Websocket disconnected without ping adaptative algorithm running');
+      this._wsWentDownCounter++;
+      if (this._wsWentDownCounter > kWS_MAX_WENTDOWN) {
+        debug('Too many disconnects. Reenabling ping adaptative algoritm');
+        this._wsWentDownCounter = 0;
+        this._recalculatePing = true;
+        this._lastGoodPingInterval = Math.floor(lastTriedPingInterval / 2);
+        nextPingInterval = this._lastGoodPingInterval;
+        prefs.set('pingInterval', nextPingInterval);
+        this._save(ns, nextPingInterval);
+        return;
+      }
+
+      debug('We do not need to recalculate the ping, based on previous data');
+    }
+
     if (wsWentDown) {
       debug('The WebSocket was disconnected, calculating next ping');
 
       // If we have not tried this pingInterval yet, initialize
       this._pingIntervalRetryTimes[lastTriedPingInterval] =
            (this._pingIntervalRetryTimes[lastTriedPingInterval] || 0) + 1;
 
        // Try the pingInterval at least 3 times, just to be sure that the
@@ -765,16 +796,20 @@ this.PushService = {
       this._recalculatePing = false;
       this._lastGoodPingInterval = lastTriedPingInterval;
       nextPingInterval = lastTriedPingInterval;
     }
 
     debug('Setting the pingInterval to ' + nextPingInterval);
     prefs.set('pingInterval', nextPingInterval);
 
+    this._save(ns, nextPingInterval);
+  },
+
+  _save: function(ns, nextPingInterval){
     //Save values for our current network
     if (ns.ip) {
       prefs.set('pingInterval.mobile', nextPingInterval);
       prefs.set('adaptive.lastGoodPingInterval.mobile', this._lastGoodPingInterval);
     } else {
       prefs.set('pingInterval.wifi', nextPingInterval);
       prefs.set('adaptive.lastGoodPingInterval.wifi', this._lastGoodPingInterval);
     }