From fe4f385e2c38676ccdb635546756b38b6a7aae79 Mon Sep 17 00:00:00 2001 From: Sebastian Spaeth Date: Mon, 12 Sep 2011 10:26:42 +0200 Subject: [PATCH] folder.IMAP: Improve dropped connection handling in quickchanged() The quickchanged() function was not handling dropped connections yet. If IMAP4.select() throws a FOLDER_RETRY error, we will now discard the connection, reconnect and retry. Signed-off-by: Sebastian Spaeth Signed-off-by: Nicolas Sebrecht --- offlineimap/folder/IMAP.py | 50 ++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/offlineimap/folder/IMAP.py b/offlineimap/folder/IMAP.py index 4dcae7d..25ebe38 100644 --- a/offlineimap/folder/IMAP.py +++ b/offlineimap/folder/IMAP.py @@ -89,27 +89,35 @@ class IMAPFolder(BaseFolder): # An IMAP folder has definitely changed if the number of # messages or the UID of the last message have changed. Otherwise # only flag changes could have occurred. - imapobj = self.imapserver.acquireconnection() - try: - # Primes untagged_responses - imaptype, imapdata = imapobj.select(self.getfullname(), readonly = 1, force = 1) - # 1. Some mail servers do not return an EXISTS response - # if the folder is empty. 2. ZIMBRA servers can return - # multiple EXISTS replies in the form 500, 1000, 1500, - # 1623 so check for potentially multiple replies. - if imapdata == [None]: - return True - maxmsgid = 0 - for msgid in imapdata: - maxmsgid = max(long(msgid), maxmsgid) - - # Different number of messages than last time? - if maxmsgid != statusfolder.getmessagecount(): - return True - - finally: - self.imapserver.releaseconnection(imapobj) - return False + retry = True # Should we attempt another round or exit? + while retry: + retry = False + imapobj = self.imapserver.acquireconnection() + try: + # Select folder and get number of messages + restype, imapdata = imapobj.select(self.getfullname(), True, + True) + except OfflineImapError, e: + # retry on dropped connections, raise otherwise + self.imapserver.releaseconnection(imapobj, true) + if e.severity == OfflineImapError.ERROR.FOLDER_RETRY: + retry = True + else: raise + finally: + self.imapserver.releaseconnection(imapobj) + # 1. Some mail servers do not return an EXISTS response + # if the folder is empty. 2. ZIMBRA servers can return + # multiple EXISTS replies in the form 500, 1000, 1500, + # 1623 so check for potentially multiple replies. + if imapdata == [None]: + return True + maxmsgid = 0 + for msgid in imapdata: + maxmsgid = max(long(msgid), maxmsgid) + # Different number of messages than last time? + if maxmsgid != statusfolder.getmessagecount(): + return True + return False def cachemessagelist(self): maxage = self.config.getdefaultint("Account %s" % self.accountname,