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
|
from optparse import OptionParser
|
||||||
|
|
||||||
import offlineimap
|
import offlineimap
|
||||||
from offlineimap import accounts, threadutil, syncmaster, folder
|
from offlineimap import accounts, threadutil, folder
|
||||||
from offlineimap import globals
|
from offlineimap import globals
|
||||||
from offlineimap.ui import UI_LIST, setglobalui, getglobalui
|
from offlineimap.ui import UI_LIST, setglobalui, getglobalui
|
||||||
from offlineimap.CustomConfig import CustomConfigParser
|
from offlineimap.CustomConfig import CustomConfigParser
|
||||||
@ -36,6 +36,28 @@ import traceback
|
|||||||
import collections
|
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:
|
class OfflineImap:
|
||||||
"""The main class that encapsulates the high level use of OfflineImap.
|
"""The main class that encapsulates the high level use of OfflineImap.
|
||||||
|
|
||||||
@ -388,9 +410,11 @@ class OfflineImap:
|
|||||||
self.__sync_singlethreaded(syncaccounts)
|
self.__sync_singlethreaded(syncaccounts)
|
||||||
else:
|
else:
|
||||||
# multithreaded
|
# multithreaded
|
||||||
t = threadutil.ExitNotifyThread(target=syncmaster.syncitall,
|
t = threadutil.ExitNotifyThread(target=syncitall,
|
||||||
name='Sync Runner',
|
name='Sync Runner',
|
||||||
kwargs={'accounts': syncaccounts, 'config': self.config})
|
kwargs={'accounts': syncaccounts, 'config': self.config})
|
||||||
|
# Special exit message for the monitor to stop looping.
|
||||||
|
t.exit_message = threadutil.STOP_MONITOR
|
||||||
t.start()
|
t.start()
|
||||||
threadutil.monitor()
|
threadutil.monitor()
|
||||||
|
|
||||||
@ -407,13 +431,12 @@ class OfflineImap:
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
def __sync_singlethreaded(self, accs):
|
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
|
:param accs: A list of accounts that should be synced
|
||||||
"""
|
"""
|
||||||
for accountname in accs:
|
for accountname in accs:
|
||||||
account = offlineimap.accounts.SyncableAccount(self.config,
|
account = accounts.SyncableAccount(self.config, accountname)
|
||||||
accountname)
|
|
||||||
threading.currentThread().name = "Account sync %s"% accountname
|
threading.currentThread().name = "Account sync %s"% accountname
|
||||||
account.syncrunner()
|
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
|
# Exit-notify threads
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
exitthreads = Queue()
|
exitedThreads = Queue()
|
||||||
|
|
||||||
def monitor():
|
def monitor():
|
||||||
"""An infinite "monitoring" loop watching for finished ExitNotifyThread's.
|
"""An infinite "monitoring" loop watching for finished ExitNotifyThread's.
|
||||||
@ -103,17 +103,20 @@ def monitor():
|
|||||||
:type callback: a callable function
|
:type callback: a callable function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
global exitthreads
|
global exitedThreads
|
||||||
ui = getglobalui()
|
ui = getglobalui()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# Loop forever and call 'callback' for each thread that exited
|
# Loop forever and call 'callback' for each thread that exited
|
||||||
try:
|
try:
|
||||||
# We need a timeout in the get() call, so that ctrl-c can throw
|
# We need a timeout in the get() call, so that ctrl-c can throw a
|
||||||
# a SIGINT (http://bugs.python.org/issue1360). A timeout with empty
|
# SIGINT (http://bugs.python.org/issue1360). A timeout with empty
|
||||||
# Queue will raise `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 thread.exit_exception is not None:
|
||||||
if isinstance(thread.exit_exception, SystemExit):
|
if isinstance(thread.exit_exception, SystemExit):
|
||||||
@ -128,6 +131,7 @@ def monitor():
|
|||||||
" and the ui did not stop the program."%
|
" and the ui did not stop the program."%
|
||||||
(repr(thread.exit_exception), type(thread.exit_exception)))
|
(repr(thread.exit_exception), type(thread.exit_exception)))
|
||||||
|
|
||||||
|
# Only the monitor thread has this exit message set.
|
||||||
elif thread.exit_message == STOP_MONITOR:
|
elif thread.exit_message == STOP_MONITOR:
|
||||||
break # Exit the loop here.
|
break # Exit the loop here.
|
||||||
else:
|
else:
|
||||||
@ -160,9 +164,9 @@ class ExitNotifyThread(Thread):
|
|||||||
self._exit_stacktrace = None
|
self._exit_stacktrace = None
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Allow profiling of a run."""
|
"""Allow profiling of a run and store exceptions."""
|
||||||
|
|
||||||
global exitthreads
|
global exitedThreads
|
||||||
try:
|
try:
|
||||||
if not ExitNotifyThread.profiledir: # normal case
|
if not ExitNotifyThread.profiledir: # normal case
|
||||||
Thread.run(self)
|
Thread.run(self)
|
||||||
@ -183,8 +187,7 @@ class ExitNotifyThread(Thread):
|
|||||||
tb = traceback.format_exc()
|
tb = traceback.format_exc()
|
||||||
self.set_exit_exception(e, tb)
|
self.set_exit_exception(e, tb)
|
||||||
|
|
||||||
if exitthreads:
|
exitedThreads.put(self, True)
|
||||||
exitthreads.put(self, True)
|
|
||||||
|
|
||||||
def set_exit_exception(self, exc, st=None):
|
def set_exit_exception(self, exc, st=None):
|
||||||
"""Sets Exception and stacktrace of a thread, so that other
|
"""Sets Exception and stacktrace of a thread, so that other
|
||||||
|
Loading…
Reference in New Issue
Block a user