Bug 1339248 - Part 2 - Move the msgDatabase check to a later point, after a successful download. r=mkmelin
authoralta88@gmail.com
Sun, 19 Feb 2017 10:03:48 -0700
changeset 21268 e3fa3b9f3d65c86ddeb67865ed821f79a261f2a9
parent 21267 848dc0659f1a243d251428a65f80b9f135f05d7c
child 21269 c1860a0bb7cabf5fa917f7ffa4819d3bd45493e3
push id12921
push usermozilla@jorgk.com
push dateTue, 07 Mar 2017 15:30:57 +0000
treeherdercomm-central@e3fa3b9f3d65 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1339248
Bug 1339248 - Part 2 - Move the msgDatabase check to a later point, after a successful download. r=mkmelin
mailnews/extensions/newsblog/content/Feed.js
mailnews/extensions/newsblog/content/FeedUtils.jsm
--- a/mailnews/extensions/newsblog/content/Feed.js
+++ b/mailnews/extensions/newsblog/content/Feed.js
@@ -285,16 +285,35 @@ Feed.prototype =
     // Simulate a cancel after a url update; next cycle will check the new url.
     aFeed.mInvalidFeed = true;
     if (aFeed.downloadCallback)
       aFeed.downloadCallback.downloaded(aFeed, FeedUtils.kNewsBlogCancel);
 
     FeedCache.removeFeed(aOldUrl);
   },
 
+  // nsIUrlListener methods for getDatabaseWithReparse().
+  OnStartRunningUrl: function(aUrl) { },
+  OnStopRunningUrl: function(aUrl, aExitCode)
+  {
+    if (Components.isSuccessCode(aExitCode))
+    {
+      FeedUtils.log.debug("Feed.OnStopRunningUrl: rebuilt msgDatabase for " +
+                          this.folder.name + " - " + this.folder.filePath.path);
+    }
+    else
+    {
+      FeedUtils.log.error("Feed.OnStopRunningUrl: rebuild msgDatabase failed, " +
+                          "error " + aExitCode + ", for " +
+                          this.folder.name + " - " + this.folder.filePath.path);
+    }
+    // Continue.
+    this.storeNextItem();
+  },
+
   get url()
   {
     let ds = FeedUtils.getSubscriptionsDS(this.server);
     let url = ds.GetTarget(this.resource, FeedUtils.DC_IDENTIFIER, true);
     if (url)
       url = url.QueryInterface(Ci.nsIRDFLiteral).Value;
     else
       url = this.resource.ValueUTF8;
@@ -439,19 +458,29 @@ Feed.prototype =
 
     if (this.mInvalidFeed)
     {
       this.request = null;
       this.mInvalidFeed = false;
       return;
     }
 
-    // storeNextItem() will iterate through the parsed items, storing each one.
     this.itemsToStoreIndex = 0;
     this.itemsStored = 0;
+
+    // At this point, if we have items to potentially store and an existing
+    // folder, ensure the folder's msgDatabase is openable for new message
+    // processing. If not, reparse with an async nsIUrlListener |this| to
+    // continue once the reparse is complete.
+    if (this.itemsToStore && this.itemsToStore.length > 0 && this.folder &&
+        !FeedUtils.isMsgDatabaseOpenable(this.folder, true, this))
+      return;
+
+    // We have an msgDatabase; storeNextItem() will iterate through the parsed
+    // items, storing each one.
     this.storeNextItem();
   },
 
   invalidateItems: function ()
   {
     let ds = FeedUtils.getItemsDS(this.server);
     FeedUtils.log.debug("Feed.invalidateItems: for url - " + this.url);
     let items = ds.GetSources(FeedUtils.FZ_FEED, this.resource, true);
@@ -540,16 +569,17 @@ Feed.prototype =
     }
 
     if (!this.itemsToStore || !this.itemsToStore.length)
     {
       let code = FeedUtils.kNewsBlogSuccess;
       this.createFolder();
       if (!this.folder)
         code = FeedUtils.kNewsBlogFileError;
+
       this.cleanupParsingState(this, code);
       return;
     }
 
     let item = this.itemsToStore[this.itemsToStoreIndex];
 
     if (item.store())
       this.itemsStored++;
--- a/mailnews/extensions/newsblog/content/FeedUtils.jsm
+++ b/mailnews/extensions/newsblog/content/FeedUtils.jsm
@@ -316,17 +316,16 @@ var FeedUtils = {
 
         FeedUtils.log.debug("downloadFeed: CONTINUE foldername:urlArray - " +
                             folder.name + " : " + feedUrlArray);
 
         FeedUtils.progressNotifier.init(aMsgWindow, false);
 
         // We need to kick off a download for each feed.
         let now = Date.now();
-        let msgDbOk = false;
         for (let url of feedUrlArray)
         {
           // Check whether this feed should be updated; if forceDownload is true
           // skip the per feed check.
           if (!forceDownload)
           {
             let status = FeedUtils.getStatus(folder, url);
             if (!status.enabled ||
@@ -359,36 +358,20 @@ var FeedUtils = {
                          FeedUtils.MAX_CONCURRENT_FEEDS)
           {
             FeedUtils.log.debug("downloadFeed: RETURN active feeds count is greater " +
                                 "than the max - " + FeedUtils.MAX_CONCURRENT_FEEDS);
             FeedUtils.progressNotifier.downloaded(feed, FeedUtils.kNewsBlogFeedIsBusy);
             return;
           }
 
-          // Ensure folder's msgDatabase is openable for new message processing.
-          // If not, reparse and break (to the next folder), as attempting to
-          // add a message to a folder with an unavailable msgDatabase will
-          // throw later. After the async reparse the folder will be ready for
-          // the next poll cycle to pick up this folder's feeds, whose update
-          // time will not have changed.
-          if (!msgDbOk) {
-            // Only do this test once on the first url ready to update.
-            msgDbOk = FeedUtils.isMsgDatabaseOpenable(folder, true);
-            if (!msgDbOk)
-            {
-              FeedUtils.progressNotifier.downloaded(feed, FeedUtils.kNewsBlogFeedIsBusy);
-              break;
-            }
-          }
-
           // Set status info and download.
+          FeedUtils.log.debug("downloadFeed: DOWNLOAD feed url - " + url);
           FeedUtils.setStatus(folder, url, "code", FeedUtils.kNewsBlogFeedIsBusy);
           feed.download(true, FeedUtils.progressNotifier);
-          FeedUtils.log.debug("downloadFeed: DOWNLOAD feed url - " + url);
 
           Services.tm.mainThread.dispatch(function() {
             try {
               let done = getFeed.next().done;
               if (done) {
                 // Finished with all feeds in base aFolder and its subfolders.
                 FeedUtils.log.debug("downloadFeed: Finished with folder - " +
                                     aFolder.name);
@@ -720,21 +703,23 @@ var FeedUtils = {
     }
 
     return feedUrlArray.length ? feedUrlArray : null;
   },
 
 /**
  * Check if the folder's msgDatabase is openable, reparse if desired.
  *
- * @param  nsIMsgFolder aFolder - the folder
- * @param  boolean aReparse     - reparse if true
+ * @param  nsIMsgFolder aFolder        - the folder
+ * @param  boolean aReparse            - reparse if true
+ * @param  nsIUrlListener aUrlListener - object implementing nsIUrlListener
+ *
  * @return boolean              - true if msgDb is available, else false
  */
-  isMsgDatabaseOpenable: function(aFolder, aReparse) {
+  isMsgDatabaseOpenable: function(aFolder, aReparse, aUrlListener) {
     let msgDb;
     try {
       msgDb = Cc["@mozilla.org/msgDatabase/msgDBService;1"]
                 .getService(Ci.nsIMsgDBService).openFolderDB(aFolder, true);
     }
     catch (ex) {}
 
     if (msgDb)
@@ -744,17 +729,17 @@ var FeedUtils = {
       return false;
 
     // Force a reparse.
     FeedUtils.log.debug("checkMsgDb: rebuild msgDatabase for " +
                         aFolder.name + " - " + aFolder.filePath.path);
     try {
       // Ignore error returns.
       aFolder.QueryInterface(Ci.nsIMsgLocalMailFolder)
-             .getDatabaseWithReparse(null, null);
+             .getDatabaseWithReparse(aUrlListener, null);
     }
     catch (ex) {}
 
     return false;
   },
 
   /**
    * Return properties for nsITreeView getCellProperties, for a tree row item in
@@ -1913,22 +1898,31 @@ var FeedUtils = {
           options.updates.enabled = false;
           feed.options = options;
           FeedUtils.setStatus(feed.folder, feed.url, "enabled", false);
           FeedUtils.log.warn("downloaded: udpates disabled due to error, " +
                              "check the url - " + feed.url);
         }
 
         if (!this.mSubscribeMode)
+        {
           FeedUtils.setStatus(feed.folder, feed.url, "code", aErrorCode);
 
-        if (feed.folder)
-          // Free msgDatabase after new mail biff is set; if busy let the next
-          // result do the freeing.  Otherwise new messages won't be indicated.
-          feed.folder.msgDatabase = null;
+          if (feed.folder &&
+              !FeedUtils.getFolderProperties(feed.folder).includes("isBusy"))
+          {
+            // Free msgDatabase after new mail biff is set; if busy let the next
+            // result do the freeing.  Otherwise new messages won't be indicated.
+            // This feed may belong to a folder with multiple other feeds, some
+            // of which may not yet be finished, so free only if the folder is
+            // no longer busy.
+            feed.folder.msgDatabase = null;
+            FeedUtils.log.debug("downloaded: msgDatabase freed - " + feed.folder.name);
+          }
+        }
       }
 
       let message = "";
       switch (aErrorCode) {
         case FeedUtils.kNewsBlogSuccess:
         case FeedUtils.kNewsBlogFeedIsBusy:
           message = "";
           break;