get rid of offlineimap/syncmaster.py
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
parent
857b2f449a
commit
7ab18276f9
@ -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()
|
||||
|
||||
|
@ -1,45 +0,0 @@
|
||||
# OfflineIMAP synchronization master code
|
||||
# Copyright (C) 2002-2007 John Goerzen
|
||||
# <jgoerzen@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.
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user