Bug 467118 - Switch search indexing over to use nsIIdleService instead of message displayed timers; r=(bienvenu + beckley)
authorSiddharth Agarwal <sid1337@gmail.com>
Sat, 06 Dec 2008 22:52:15 +0100
changeset 1352 db341efa61d3b76740ffdf289a15bb79b7865c4c
parent 1351 825465d0c6834268a9b704a44f8c069798956c83
child 1353 aaf8120249081d283bf9d81f7fcdbc05ffa3e762
push id1063
push usersgautherie.bz@free.fr
push dateSat, 06 Dec 2008 21:52:30 +0000
treeherdercomm-central@db341efa61d3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs467118
Bug 467118 - Switch search indexing over to use nsIIdleService instead of message displayed timers; r=(bienvenu + beckley)
mail/components/search/content/searchCommon.js
--- a/mail/components/search/content/searchCommon.js
+++ b/mail/components/search/content/searchCommon.js
@@ -56,23 +56,32 @@ const Cu = Components.utils;
 Cu.import("resource://gre/modules/iteratorUtils.jsm");
 Cu.import("resource://app/modules/gloda/log4moz.js");
 
 var gCurrentFolderToIndex;
 var gLastFolderIndexedUri = ""; // this is stored in a pref
 var gHeaderEnumerator;
 var gMsgHdrsToIndex;
 var gMessenger;
-var gAlarm;
 var gBackgroundIndexingDone;
 var gPrefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).getBranch(null);
 var gEnabled;
 
 let SearchIntegration = this;
 
+/**
+ * Amount of time the user is idle before we (re)start an indexing sweep
+ */
+let _idleThresholdSecs = 30;
+
+/**
+ * Reference to current timer object
+ */
+let _timer = null;
+
 /*
  * Init function -- this should be called from the component's init function
  */
 function InitSupportIntegration(enabled)
 {
   this._log.info("Search integration running in " + (enabled ? "active" : "backoff") + " mode");
   gEnabled = enabled;
 
@@ -84,23 +93,27 @@ function InitSupportIntegration(enabled)
   // We want to observe moves, deletes and renames in case we're disabled
   // If we don't, we'll have no idea the support files exist later
   if (enabled)
   {
     notificationService.addListener(gFolderListener, notificationService.all);
     var ObserverService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
     ObserverService.addObserver(MsgMsgDisplayedObserver, "MsgMsgDisplayed", false);
     gMsgHdrsToIndex = new Array();
-
-    restartTimer(60);
+    let idleService = Cc["@mozilla.org/widget/idleservice;1"].
+                          getService(Ci.nsIIdleService);
+    idleService.addIdleObserver(this._idleObserver, this._idleThresholdSecs);
   }
   else
     notificationService.addListener(gFolderListener, notificationService.msgsMoveCopyCompleted |
                                     notificationService.msgsDeleted |
                                     notificationService.allFolderNotifications);
+
+  // Set up the timer, though we'll only init it later when needed
+  this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
 }
 
 /*
  * These functions are to index already existing messages
  */
 function FindNextFolderToIndex()
 {
   accountManager = Cc["@mozilla.org/messenger/account-manager;1"].getService(Ci.nsIMsgAccountManager);
@@ -151,17 +164,17 @@ function FindNextHdrToIndex()
         return msgHdr;
     }
   }
   catch(ex) {}
   gHeaderEnumerator = null;
   return null;
 }
 
-function onTimer()
+function _continueSweep()
 {
   var msgHdrToIndex = null;
 
   if (gBackgroundIndexingDone)
     return;
 
   // find the current folder we're working on
   if (!gCurrentFolderToIndex)
@@ -190,40 +203,60 @@ function onTimer()
       gPrefBranch.setCharPref(gPrefBase + ".lastFolderIndexedUri", gLastFolderIndexedUri);
       gCurrentFolderToIndex = null;
     }
   }
   else
   {
     QueueMessageToGetIndexed(msgHdrToIndex);
   }
-  restartTimer(gMsgHdrsToIndex.length > 1 ? 5 : 1);
+
+  // Restart the timer, and call ourselves
+  try {
+    SearchIntegration._timer.cancel();
+  } catch (ex) {}
+  SearchIntegration._timer
+    .initWithCallback(arguments.callee,
+                      gMsgHdrsToIndex.length > 1 ? 5000 : 1000,
+                      Ci.nsITimer.TYPE_ONE_SHOT);
 }
 
-function restartTimer(seconds)
+/**
+ * Idle observer; starts running through folders when it receives an "idle"
+ * notification, and cancels any timers when it receives a "back" notification.
+ */
+let _idleObserver =
 {
-  if (gAlarm)
-    gAlarm.cancel();
-  var jslib = Cc["@mozilla.org/url-classifier/jslib;1"]
-    .getService().wrappedJSObject;
-
-  gAlarm = new jslib.G_Alarm(onTimer, seconds*1000);
-}
+  observe: function search_idle_observe(aSubject, aTopic, aData)
+  {
+    if (aTopic == "idle")
+    {
+      SearchIntegration._log.debug("Idle detected, continuing sweep")
+      // We call _continueSweep this way to be neater there
+      SearchIntegration._continueSweep();
+    }
+    else if (aTopic == "back")
+    {
+      SearchIntegration._log.debug("Non-idle, so suspending sweep")
+      try {
+        SearchIntegration._timer.cancel();
+      } catch (ex) {}
+    }
+  }
+};
 
 /*
  * This object gets notifications for messages that are read, giving them a
  * higher priority
  */
 var MsgMsgDisplayedObserver =
 {
   // Components.interfaces.nsIObserver
   observe: function(aHeaderSink, aTopic, aData)
-    {
-    // if the user is reading messages, we're not idle, so restart timer.
-    restartTimer(60);
+  {
     SearchIntegration._log.debug("topic = " + aTopic + " uri = " + aData);
     var msgHdr = gMessenger.msgHdrFromURI(aData);
     var indexed = msgHdr.getUint32Property(gHdrIndexedProperty);
     if (!indexed)
     {
       var file = GetSupportFileForMsgHdr(msgHdr);
       if (!file.exists())
         QueueMessageToGetIndexed(msgHdr);
@@ -233,29 +266,25 @@ var MsgMsgDisplayedObserver =
 
 /*
  * This object gets notifications for new/moved/copied/deleted messages/folders
  */
 var gFolderListener = {
   msgAdded: function(aMsg)
   {
     SearchIntegration._log.info("in msgAdded");
-    restartTimer(30);
     // The message already being there is an expected case
     var file = GetSupportFileForMsgHdr(aMsg);
     if (!file.exists())
       QueueMessageToGetIndexed(aMsg);
   },
 
   msgsDeleted: function(aMsgs)
   {
     SearchIntegration._log.info("in msgsDeleted");
-    // mail getting deleted, we're not idle, so restart timer.
-    if (gEnabled)
-      restartTimer(60);
     var count = aMsgs.length;
     for (var i = 0; i < count; i++)
     {
       var file = GetSupportFileForMsgHdr(aMsgs.queryElementAt(i, Ci.nsIMsgDBHdr));
       if (file.exists())
         file.remove(false);
     }
   },
@@ -286,18 +315,16 @@ var gFolderListener = {
         // We're not going to copy in case we're not in active mode
         if (destFile.exists())
           if (aMove)
             srcFile.moveTo(destFile, "");
           else if (gEnabled)
             srcFile.copyTo(destFile, "");
       }
     }
-    if (gEnabled)
-      restartTimer(30);
   },
 
   folderDeleted: function(aFolder)
   {
     SearchIntegration._log.info("in folderDeleted, folder name = " +
                                 aFolder.prettiestName);
     var srcFile = aFolder.filePath;
     srcFile.leafName = srcFile.leafName + ".mozmsgs";