[geary/mjog/797-sync-recoverable-error-loop] ImapEngine.MinimalFolder: Add workaround for infinite "recoverable error"




commit 117051e5b31ae3cd19e9dd1b8e9a7f5df98b2381
Author: Michael Gratton <mike vee net>
Date:   Tue Sep 1 22:01:42 2020 +1000

    ImapEngine.MinimalFolder: Add workaround for infinite "recoverable error"
    
    Workaround for infinite "recoverable error" loop on sync when the
    folder's network connection has gone away unnoticed.
    
    Fixes #797

 src/engine/imap-engine/imap-engine-minimal-folder.vala | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)
---
diff --git a/src/engine/imap-engine/imap-engine-minimal-folder.vala 
b/src/engine/imap-engine/imap-engine-minimal-folder.vala
index 231591474..ee2f97b14 100644
--- a/src/engine/imap-engine/imap-engine-minimal-folder.vala
+++ b/src/engine/imap-engine/imap-engine-minimal-folder.vala
@@ -304,8 +304,8 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
         throws GLib.Error {
         check_open("synchronise_remote");
 
-        bool have_nooped = false;
-        while (!have_nooped && !cancellable.is_cancelled()) {
+        int retries = 3;
+        while (retries > 0 && !cancellable.is_cancelled()) {
             // The normalisation process will pick up any missing
             // messages if closed, so ensure there is a remote
             // session.
@@ -323,11 +323,21 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
                 // showing the Sent folder, IDLE won't be enabled and
                 // hence we won't get notified of the saved mail.
                 yield remote.send_noop(cancellable);
-                have_nooped = true;
             } catch (GLib.Error err) {
-                if (is_recoverable_failure(err)) {
+                if (is_recoverable_failure(err) && retries > 1) {
+                    // XXX In theory we should be able to just retry
+                    // this immediately, but there's a race between
+                    // the old connection being disposed and another
+                    // being obtained that can make this into an
+                    // infinite loop. So limit the maximum number of
+                    // reties and set a timeout to help aid recovery.
                     debug("Recoverable error during remote sync: %s",
                           err.message);
+                    retries--;
+                    GLib.Timeout.add_seconds(
+                        1, this.synchronise_remote.callback
+                    );
+                    yield;
                 } else {
                     throw err;
                 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]