Bug 1045163 - Remove delay before updating existing tables on disk. r=gcp, a=sledru
authorMonica Chew <mmc@mozilla.com>
Fri, 08 Aug 2014 13:56:27 -0700
changeset 217460 2211ef492219bf2a63e99e188b1812935e1590cc
parent 217459 95776d575df5b7cfe0f721c490617dc43d7e26a0
child 217461 5c3ac814a2873fd0b2218cc726820929781a06a2
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)
reviewersgcp, sledru
bugs1045163
milestone33.0a2
Bug 1045163 - Remove delay before updating existing tables on disk. r=gcp, a=sledru
toolkit/components/url-classifier/content/listmanager.js
--- a/toolkit/components/url-classifier/content/listmanager.js
+++ b/toolkit/components/url-classifier/content/listmanager.js
@@ -56,16 +56,20 @@ function PROT_ListManager() {
   //                              goog-malware-shavar: true }
   this.needsUpdate_ = {};
 
   this.observerServiceObserver_ = new G_ObserverServiceObserver(
                                           'quit-application',
                                           BindToObject(this.shutdown_, this),
                                           true /*only once*/);
 
+  // A map of updateUrls to single-use G_Alarms. An entry exists if and only if
+  // there is at least one table with updates enabled for that url. G_Alarms
+  // are reset when enabling/disabling updates or on update callbacks (update
+  // success, update failure, download error).
   this.updateCheckers_ = {};
   this.requestBackoffs_ = {};
   this.dbService_ = Cc["@mozilla.org/url-classifier/dbservice;1"]
                    .getService(Ci.nsIUrlClassifierDBService);
 
 
   this.hashCompleter_ = Cc["@mozilla.org/url-classifier/hashcompleter;1"]
                         .getService(Ci.nsIUrlClassifierHashCompleter);
@@ -136,26 +140,43 @@ PROT_ListManager.prototype.enableUpdate 
   var table = this.tablesData[tableName];
   if (table) {
     log("Enabling table updates for " + tableName);
     this.needsUpdate_[table.updateUrl][tableName] = true;
   }
 }
 
 /**
+ * Returns true if any table associated with the updateUrl requires updates.
+ * @param updateUrl - the updateUrl
+ */
+PROT_ListManager.prototype.updatesNeeded_ = function(updateUrl) {
+  let updatesNeeded = false;
+  for (var tableName in this.needsUpdate_[updateUrl]) {
+    if (this.needsUpdate_[updateUrl][tableName]) {
+      updatesNeeded = true;
+    }
+  }
+  return updatesNeeded;
+}
+
+/**
  * Disables updates for some tables
  * @param tables - an array of table names that no longer need updating
  */
 PROT_ListManager.prototype.disableUpdate = function(tableName) {
-  var changed = false;
   var table = this.tablesData[tableName];
   if (table) {
     log("Disabling table updates for " + tableName);
     this.needsUpdate_[table.updateUrl][tableName] = false;
-    changed = true;
+    if (!this.updatesNeeded_(table.updateUrl) &&
+        this.updateCheckers_[table.updateUrl]) {
+      this.updateCheckers_[table.updateUrl].cancel();
+      this.updateCheckers_[table.updateUrl] = null;
+    }
   }
 }
 
 /**
  * Determine if we have some tables that need updating.
  */
 PROT_ListManager.prototype.requireTableUpdates = function() {
   for (var name in this.tablesData) {
@@ -171,44 +192,31 @@ PROT_ListManager.prototype.requireTableU
 /**
  * Acts as a nsIUrlClassifierCallback for getTables.
  */
 PROT_ListManager.prototype.kickoffUpdate_ = function (onDiskTableData)
 {
   this.startingUpdate_ = false;
   var initialUpdateDelay = 3000;
 
-  // Check if any table registered for updates has ever been downloaded.
-  var updatingExisting = false;
-  for (var tableName in this.tablesData) {
-    if (this.needsUpdate_[this.tablesData[tableName].updateUrl][tableName]) {
-      if (onDiskTableData.indexOf(tableName) != -1) {
-        updatingExisting = true;
-      }
-    }
-  }
-
   // If the user has never downloaded tables, do the check now.
   log("needsUpdate: " + JSON.stringify(this.needsUpdate_, undefined, 2));
   for (var updateUrl in this.needsUpdate_) {
-    // If the user has tables, add a fuzz of a few minutes.
-    if (updatingExisting) {
-      // Add a fuzz of 0-5 minutes.
-      initialUpdateDelay += Math.floor(Math.random() * (5 * 60 * 1000));
-      log("Waiting " + initialUpdateDelay / 1000 +
-          " for updating existing table from " + updateUrl);
-    }
     // If we haven't already kicked off updates for this updateUrl, set a
     // non-repeating timer for it. The timer delay will be reset either on
     // updateSuccess to this.updateinterval, or backed off on downloadError.
-    if (!this.updateCheckers_[updateUrl]) {
+    // Don't set the updateChecker unless at least one table has updates
+    // enabled.
+    if (this.updatesNeeded_(updateUrl) && !this.updateCheckers_[updateUrl]) {
       log("Initializing update checker for " + updateUrl);
       this.updateCheckers_[updateUrl] =
         new G_Alarm(BindToObject(this.checkForUpdates, this, updateUrl),
                     initialUpdateDelay, false /* repeating */);
+    } else {
+      log("No updates needed or already initialized for " + updateUrl);
     }
   }
 }
 
 PROT_ListManager.prototype.stopUpdateCheckers = function() {
   log("Stopping updates");
   for (var updateUrl in this.updateCheckers_) {
     this.updateCheckers_[updateUrl].cancel();
@@ -338,16 +346,17 @@ PROT_ListManager.prototype.makeUpdateReq
 
   log("update request: " + JSON.stringify(streamerMap, undefined, 2) + "\n");
 
   // Don't send an empty request.
   if (streamerMap.request.length > 0) {
     this.makeUpdateRequestForEntry_(updateUrl, streamerMap.tableList,
                                     streamerMap.request);
   } else {
+    // We were disabled between kicking off getTables and now.
     log("Not sending empty request");
   }
 }
 
 PROT_ListManager.prototype.makeUpdateRequestForEntry_ = function(updateUrl,
                                                                  tableList,
                                                                  request) {
   log("makeUpdateRequestForEntry_: request " + request +