Bug 1511111 - Optimize UrlClassifierSkipListService listening for RemoteSettings sync and fall back to empty collection in case of DB errors. r=leplatrem
authorJohann Hofmann <jhofmann@mozilla.com>
Fri, 08 Mar 2019 22:21:48 +0000
changeset 521205 2860c54eca91
parent 521204 70d4aa69497a
child 521206 e42dc1d5f378
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersleplatrem
bugs1511111
milestone67.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 1511111 - Optimize UrlClassifierSkipListService listening for RemoteSettings sync and fall back to empty collection in case of DB errors. r=leplatrem Differential Revision: https://phabricator.services.mozilla.com/D22292
netwerk/url-classifier/UrlClassifierSkipListService.jsm
--- a/netwerk/url-classifier/UrlClassifierSkipListService.jsm
+++ b/netwerk/url-classifier/UrlClassifierSkipListService.jsm
@@ -18,29 +18,29 @@ class Feature {
     this.observers = new Set();
     this.prefValue = null;
     this.remoteEntries = null;
 
     if (prefName) {
       this.prefValue = Services.prefs.getStringPref(this.prefName, null);
       Services.prefs.addObserver(prefName, this);
     }
-
-    RemoteSettings(COLLECTION_NAME).on("sync", event => {
-      let { data: { current } } = event;
-      this.remoteEntries = current;
-      this.notifyObservers();
-    });
   }
 
   async addObserver(observer) {
     // If the remote settings list hasn't been populated yet we have to make sure
     // to do it before firing the first notification.
     if (!this.remoteEntries) {
-      this.remoteEntries = await RemoteSettings(COLLECTION_NAME).get({ syncIfEmpty: false });
+      let remoteEntries;
+      try {
+        remoteEntries = await RemoteSettings(COLLECTION_NAME).get({ syncIfEmpty: false });
+      } catch (e) {
+        remoteEntries = [];
+      }
+      this.onRemoteSettingsUpdate(remoteEntries);
     }
 
     this.observers.add(observer);
     this.notifyObservers(observer);
   }
 
   removeObserver(observer) {
     this.observers.delete(observer);
@@ -51,53 +51,80 @@ class Feature {
       Cu.reportError(`Unexpected event ${topic} with ${data}`);
       return;
     }
 
     this.prefValue = Services.prefs.getStringPref(this.prefName, null);
     this.notifyObservers();
   }
 
+  onRemoteSettingsUpdate(entries) {
+    this.remoteEntries = [];
+    for (let entry of entries) {
+      if (entry.feature == this.name) {
+        this.remoteEntries.push(entry.pattern.toLowerCase());
+      }
+    }
+  }
+
   notifyObservers(observer = null) {
     let entries = [];
     if (this.prefValue) {
       entries = this.prefValue.split(",");
     }
 
     for (let entry of this.remoteEntries) {
-      if (entry.feature == this.name) {
-        entries.push(entry.pattern.toLowerCase());
-      }
+      entries.push(entry);
     }
 
     let entriesAsString = entries.join(",");
     if (observer) {
       observer.onSkipListUpdate(entriesAsString);
     } else {
       for (let obs of this.observers) {
         obs.onSkipListUpdate(entriesAsString);
       }
     }
   }
 }
 
-UrlClassifierSkipListService.prototype = Object.freeze({
+UrlClassifierSkipListService.prototype = {
   classID: Components.ID("{b9f4fd03-9d87-4bfd-9958-85a821750ddc}"),
   QueryInterface: ChromeUtils.generateQI([Ci.nsIUrlClassifierSkipListService]),
 
   features: {},
+  _initialized: false,
+
+  lazyInit() {
+    if (this._initialized) {
+      return;
+    }
+
+    RemoteSettings(COLLECTION_NAME).on("sync", event => {
+      let { data: { current } } = event;
+      for (let key of Object.keys(this.features)) {
+        let feature = this.features[key];
+        feature.onRemoteSettingsUpdate(current);
+        feature.notifyObservers();
+      }
+    });
+
+    this._initialized = true;
+  },
 
   registerAndRunSkipListObserver(feature, prefName, observer) {
+    this.lazyInit();
+
     if (!this.features[feature]) {
       this.features[feature] = new Feature(feature, prefName);
     }
     this.features[feature].addObserver(observer);
   },
 
   unregisterSkipListObserver(feature, observer) {
     if (!this.features[feature]) {
       return;
     }
     this.features[feature].removeObserver(observer);
   },
-});
+};
 
 var EXPORTED_SYMBOLS = ["UrlClassifierSkipListService"];