Bug 1554387 - do not start new periodic filter if one is already running. r=mkmelin
authoraceman <acelists@atlas.sk>
Sat, 25 May 2019 06:26:00 +0200
changeset 35693 066da1c827a51483d07a8b64b09497fcc320b812
parent 35692 166ea12f3b4bbea3f958baf85096983f5f181959
child 35694 19ec36793dc973a57edaa762922b204647467855
push id392
push userclokep@gmail.com
push dateMon, 02 Sep 2019 20:17:19 +0000
reviewersmkmelin
bugs1554387
Bug 1554387 - do not start new periodic filter if one is already running. r=mkmelin
mailnews/base/search/src/PeriodicFilterManager.jsm
--- a/mailnews/base/search/src/PeriodicFilterManager.jsm
+++ b/mailnews/base/search/src/PeriodicFilterManager.jsm
@@ -22,16 +22,17 @@ const log = Log4Moz.getConfiguredLogger(
                                         Log4Moz.Level.Warn);
 
 var PeriodicFilterManager = {
   _timer: null,
   _checkRateMilliseconds: 60000, // How often do we check if servers are ready to run?
   _defaultFilterRateMinutes: Services.prefs.getDefaultBranch("")
                                .getIntPref("mail.server.default.periodicFilterRateMinutes"),
   _initialized: false, // Has this been initialized?
+  _running: false,  // Are we executing filters already?
 
   // Initial call to begin startup.
   setupFiltering() {
     if (this._initialized)
       return;
 
     this._initialized = true;
     Services.obs.addObserver(this, "mail-startup-done");
@@ -55,19 +56,32 @@ var PeriodicFilterManager = {
 
     // kickoff the timer to run periodic filters
     this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
     this._timer.initWithCallback(this, this._checkRateMilliseconds,
                                  Ci.nsITimer.TYPE_REPEATING_SLACK);
     Services.obs.addObserver(this, "quit-application-granted");
   },
 
-  // periodic callback
+  /**
+   * Periodic callback to check if any periodic filters need to be run.
+   *
+   * The periodic filter manager does not guarantee that filters will be run
+   * precisely at the specified interval.
+   * The server may be busy (e.g. downloading messages) or another filter run
+   * is still ongoing, in which cases running periodic filter of any server
+   * may be postponed.
+   */
   notify(timer) {
     log.debug("PeriodicFilterManager timer callback");
+    if (this._running) {
+      log.debug("PeriodicFilterManager Previous filter run still executing");
+      return;
+    }
+    this._running = true;
     let servers = MailServices.accounts.allServers;
     let nowTime = parseInt(Date.now() / 60000);
     for (let server of fixIterator(servers, Ci.nsIMsgIncomingServer)) {
       if (!server.canHaveFilters)
         continue;
       if (server.getIntValue("nextFilterTime") > nowTime)
         continue;
       if (server.serverBusy)
@@ -94,18 +108,25 @@ var PeriodicFilterManager = {
             (curFilter.filterType & Ci.nsMsgFilterType.Periodic)) {
           tempFilterList.insertFilterAt(newFilterIndex, curFilter);
           newFilterIndex++;
         }
       }
       log.debug("PeriodicFilterManager apply periodic filters to server " + server.prettyName);
       MailServices.filters.applyFiltersToFolders(tempFilterList, foldersToFilter, null);
     }
+    this._running = false;
   },
 
+  /**
+   * Gets the periodic filter interval for the given server.
+   * If the server's interval is not sane, clean it up.
+   *
+   * @param {nsIMsgIncomingServer} server  The server to return interval for.
+   */
   getServerPeriod(server) {
     const minimumPeriodMinutes = 1;
     let serverRateMinutes = server.getIntValue("periodicFilterRateMinutes");
     // Check if period is too short.
     if (serverRateMinutes < minimumPeriodMinutes) {
       // If the server.default pref is too low, clear that one first.
       if (Services.prefs.getIntPref("mail.server.default.periodicFilterRateMinutes")
           == serverRateMinutes) {