[PATCH 3/4] get rid of offlineimap/syncmaster.py
Nicolas Sebrecht
nicolas.s-dev at laposte.net
Tue May 17 01:45:59 BST 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