[PATCH 3/4] get rid of offlineimap/syncmaster.py

Nicolas Sebrecht nicolas.s-dev at laposte.net
Tue May 17 00:45:59 UTC 2016


Signed-off-by: Nicolas Sebrecht <nicolas.s-dev at laposte.net>
---
 offlineimap/init.py       | 33 ++++++++++++++++++++++++++++-----
 offlineimap/syncmaster.py | 45 ---------------------------------------------
 offlineimap/threadutil.py | 23 +++++++++++++----------
 3 files changed, 41 insertions(+), 60 deletions(-)
 delete mode 100644 offlineimap/syncmaster.py

diff --git a/offlineimap/init.py b/offlineimap/init.py
index 1e2917e..9a6e959 100644
--- a/offlineimap/init.py
+++ b/offlineimap/init.py
@@ -25,7 +25,7 @@ import logging
 from optparse import OptionParser
 
 import offlineimap
-from offlineimap import accounts, threadutil, syncmaster, folder
+from offlineimap import accounts, threadutil, folder
 from offlineimap import globals
 from offlineimap.ui import UI_LIST, setglobalui, getglobalui
 from offlineimap.CustomConfig import CustomConfigParser
@@ -36,6 +36,28 @@ import traceback
 import collections
 
 
+def syncaccount(config, accountname):
+    """Return a new running thread for this account."""
+
+    account = accounts.SyncableAccount(config, accountname)
+    thread = threadutil.InstanceLimitedThread(instancename = 'ACCOUNTLIMIT',
+                                   target = account.syncrunner,
+                                   name = "Account sync %s" % accountname)
+    thread.setDaemon(True)
+    thread.start()
+    return thread
+
+def syncitall(accounts, config):
+    """The target when in multithreading mode for running accounts threads."""
+
+    threads = threadutil.accountThreads() # The collection of accounts threads.
+    for accountname in accounts:
+        # Start a new thread per account and store it in the collection.
+        threads.add(syncaccount(config, accountname))
+    # Wait for the threads to finish.
+    threads.wait() # Blocks until all accounts are processed.
+
+
 class OfflineImap:
     """The main class that encapsulates the high level use of OfflineImap.
 
@@ -388,9 +410,11 @@ class OfflineImap:
                 self.__sync_singlethreaded(syncaccounts)
             else:
                 # multithreaded
-                t = threadutil.ExitNotifyThread(target=syncmaster.syncitall,
+                t = threadutil.ExitNotifyThread(target=syncitall,
                     name='Sync Runner',
                     kwargs={'accounts': syncaccounts, 'config': self.config})
+                # Special exit message for the monitor to stop looping.
+                t.exit_message = threadutil.STOP_MONITOR
                 t.start()
                 threadutil.monitor()
 
@@ -407,13 +431,12 @@ class OfflineImap:
             return 1
 
     def __sync_singlethreaded(self, accs):
-        """Executed if we do not want a separate syncmaster thread
+        """Executed in singlethreaded mode only.
 
         :param accs: A list of accounts that should be synced
         """
         for accountname in accs:
-            account = offlineimap.accounts.SyncableAccount(self.config,
-                                                           accountname)
+            account = accounts.SyncableAccount(self.config, accountname)
             threading.currentThread().name = "Account sync %s"% accountname
             account.syncrunner()
 
diff --git a/offlineimap/syncmaster.py b/offlineimap/syncmaster.py
deleted file mode 100644
index e469f2c..0000000
--- a/offlineimap/syncmaster.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# OfflineIMAP synchronization master code
-# Copyright (C) 2002-2007 John Goerzen
-# <jgoerzen at complete.org>
-#
-#    This program is free software; you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation; either version 2 of the License, or
-#    (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
-
-from offlineimap.threadutil import accountThreads, InstanceLimitedThread, STOP_MONITOR
-from offlineimap.accounts import SyncableAccount
-from threading import currentThread
-
-def syncaccount(config, accountname):
-    """Return a new running thread for this account."""
-
-    account = SyncableAccount(config, accountname)
-    thread = InstanceLimitedThread(instancename = 'ACCOUNTLIMIT',
-                                   target = account.syncrunner,
-                                   name = "Account sync %s" % accountname)
-    thread.setDaemon(True)
-    thread.start()
-    return thread
-
-def syncitall(accounts, config):
-    """The target when in multithreading mode for running accounts threads."""
-
-    # Special exit message for the monitor to stop looping so the main thread
-    # can exit.
-    currentThread().exit_message = STOP_MONITOR
-    threads = accountThreads() # The collection of accounts threads.
-    for accountname in accounts:
-        # Start a new thread per account and store it in the collection.
-        threads.add(syncaccount(config, accountname))
-    # Wait for the threads to finish.
-    threads.wait() # Blocks until all accounts are processed.
diff --git a/offlineimap/threadutil.py b/offlineimap/threadutil.py
index 9e7238b..7ad8ca4 100644
--- a/offlineimap/threadutil.py
+++ b/offlineimap/threadutil.py
@@ -84,7 +84,7 @@ class accountThreads(object):
 # Exit-notify threads
 ######################################################################
 
-exitthreads = Queue()
+exitedThreads = Queue()
 
 def monitor():
     """An infinite "monitoring" loop watching for finished ExitNotifyThread's.
@@ -103,17 +103,20 @@ def monitor():
     :type callback:  a callable function
     """
 
-    global exitthreads
+    global exitedThreads
     ui = getglobalui()
 
     while True:
         # Loop forever and call 'callback' for each thread that exited
         try:
-            # We need a timeout in the get() call, so that ctrl-c can throw
-            # a SIGINT (http://bugs.python.org/issue1360). A timeout with empty
+            # We need a timeout in the get() call, so that ctrl-c can throw a
+            # SIGINT (http://bugs.python.org/issue1360). A timeout with empty
             # Queue will raise `Empty`.
-            thread = exitthreads.get(True, 60)
-            # request to abort when callback returns true
+            #
+            # ExitNotifyThread add themselves to the exitedThreads queue once
+            # they are done (normally or with exception).
+            thread = exitedThreads.get(True, 60)
+            # Request to abort when callback returns True.
 
             if thread.exit_exception is not None:
                 if isinstance(thread.exit_exception, SystemExit):
@@ -128,6 +131,7 @@ def monitor():
                     " and the ui did not stop the program."%
                     (repr(thread.exit_exception), type(thread.exit_exception)))
 
+            # Only the monitor thread has this exit message set.
             elif thread.exit_message == STOP_MONITOR:
                 break # Exit the loop here.
             else:
@@ -160,9 +164,9 @@ class ExitNotifyThread(Thread):
         self._exit_stacktrace = None
 
     def run(self):
-        """Allow profiling of a run."""
+        """Allow profiling of a run and store exceptions."""
 
-        global exitthreads
+        global exitedThreads
         try:
             if not ExitNotifyThread.profiledir: # normal case
                 Thread.run(self)
@@ -183,8 +187,7 @@ class ExitNotifyThread(Thread):
             tb = traceback.format_exc()
             self.set_exit_exception(e, tb)
 
-        if exitthreads:
-            exitthreads.put(self, True)
+        exitedThreads.put(self, True)
 
     def set_exit_exception(self, exc, st=None):
         """Sets Exception and stacktrace of a thread, so that other
-- 
2.7.4




More information about the OfflineIMAP-project mailing list