[PATCH 4/4] Implement single threading mode
Sebastian Spaeth
Sebastian at SSpaeth.de
Mon Jan 10 10:00:41 GMT 2011
Don't sync accounts in subthreads when:
1) option singlethreading has been chosen
2) There is only 1 account to sync
3) maxacountsync setting is 1 (default)
Do note that in cases 2) and 3) each account will still be synced in
multithreaded fashion (within the account), we will just not spawn
separate threads to launch and supervise the account synchronization.
Signed-off-by: Sebastian Spaeth <Sebastian at SSpaeth.de>
---
offlineimap/init.py | 64 ++++++++++++++++++++++++++------------------
offlineimap/syncmaster.py | 4 +--
2 files changed, 39 insertions(+), 29 deletions(-)
diff --git a/offlineimap/init.py b/offlineimap/init.py
index 4347bf1..f1f1bd6 100644
--- a/offlineimap/init.py
+++ b/offlineimap/init.py
@@ -17,17 +17,11 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import imaplib
-from offlineimap import imapserver, threadutil, version, syncmaster, accounts
+import offlineimap
+import offlineimap.accounts
from offlineimap.localeval import LocalEval
from offlineimap.threadutil import InstanceLimitedThread, ExitNotifyThread
-import offlineimap.ui
from offlineimap.CustomConfig import CustomConfigParser
-from optparse import OptionParser
-import re, os, sys
-from threading import *
-import threading, socket
-import signal
-import logging
try:
import fcntl
@@ -174,7 +168,7 @@ class OfflineImap:
options.singlethreaded = True
profiledir = options.profiledir
os.mkdir(profiledir)
- threadutil.setprofiledir(profiledir)
+ offlineimap.threadutil.setprofiledir(profiledir)
logging.warn("Profile mode: Potentially large data will be "
"created in '%s'" % profiledir)
@@ -221,18 +215,18 @@ class OfflineImap:
if options.runonce:
# FIXME: maybe need a better
- for section in accounts.getaccountlist(config):
+ for section in offlineimap.accounts.getaccountlist(config):
config.remove_option('Account ' + section, "autorefresh")
if options.quick:
- for section in accounts.getaccountlist(config):
+ for section in offlineimap.accounts.getaccountlist(config):
config.set('Account ' + section, "quick", '-1')
if options.folders:
foldernames = options.folders.replace(" ", "").split(",")
folderfilter = "lambda f: f in %s" % foldernames
folderincludes = "[]"
- for accountname in accounts.getaccountlist(config):
+ for accountname in offlineimap.accounts.getaccountlist(config):
account_section = 'Account ' + accountname
remote_repo_section = 'Repository ' + \
config.get(account_section, 'remoterepository')
@@ -272,7 +266,7 @@ class OfflineImap:
activeaccounts = options.accounts
activeaccounts = activeaccounts.replace(" ", "")
activeaccounts = activeaccounts.split(",")
- allaccounts = accounts.AccountHashGenerator(config)
+ allaccounts = offlineimap.accounts.AccountHashGenerator(config)
syncaccounts = []
for account in activeaccounts:
@@ -291,19 +285,16 @@ class OfflineImap:
remoterepos = None
localrepos = None
- if options.singlethreading:
- threadutil.initInstanceLimit("ACCOUNTLIMIT", 1)
- else:
- threadutil.initInstanceLimit("ACCOUNTLIMIT",
- config.getdefaultint("general", "maxsyncaccounts", 1))
+ offlineimap.threadutil.initInstanceLimit("ACCOUNTLIMIT",
+ config.getdefaultint("general", "maxsyncaccounts", 1))
for reposname in config.getsectionlist('Repository'):
for instancename in ["FOLDER_" + reposname,
"MSGCOPY_" + reposname]:
if options.singlethreading:
- threadutil.initInstanceLimit(instancename, 1)
+ offlineimap.threadutil.initInstanceLimit(instancename, 1)
else:
- threadutil.initInstanceLimit(instancename,
+ offlineimap.threadutil.initInstanceLimit(instancename,
config.getdefaultint('Repository ' + reposname, "maxconnections", 1))
siglisteners = []
def sig_handler(signum, frame):
@@ -324,15 +315,24 @@ class OfflineImap:
signal.signal(signal.SIGUSR1,sig_handler)
signal.signal(signal.SIGUSR2,sig_handler)
- threadutil.initexitnotify()
- t = ExitNotifyThread(target=syncmaster.syncitall,
+ #various initializations that need to be performed:
+ offlineimap.threadutil.initexitnotify() #TODO: Why?
+ offlineimap.mbnames.init(config, syncaccounts)
+
+ if options.singlethreading or len(syncaccounts) == 1 \
+ or config.getdefaultint("general", "maxsyncaccounts", 1) == 1:
+ #singlethreaded
+ self.sync_singlethreaded(syncaccounts, config, siglisteners)
+ else:
+ # multithreaded
+ t = ExitNotifyThread(target=offlineimap.syncmaster.syncitall,
name='Sync Runner',
kwargs = {'accounts': syncaccounts,
'config': config,
'siglisteners': siglisteners})
- t.setDaemon(1)
- t.start()
- threadutil.exitnotifymonitorloop(threadutil.threadexited)
+ t.setDaemon(1)
+ t.start()
+ offlineimap.threadutil.exitnotifymonitorloop(offlineimap.threadutil.threadexited)
except KeyboardInterrupt:
ui.terminate(1, errormsg = 'CTRL-C pressed, aborting...')
@@ -342,4 +342,16 @@ class OfflineImap:
except:
ui.mainException()
-
+ def sync_singlethreaded(self, accounts, config, siglisteners):
+ """Executed if we do not want a separate syncmaster thread
+
+ :param accounts: A list of accounts that should be synced
+ :param config: The CustomConfig object
+ :param siglisteners: The signal listeners list, defined in run()
+ """
+ for accountname in accounts:
+ account = offlineimap.accounts.SyncableAccount(config, accountname)
+ siglistener = offlineimap.accounts.SigListener()
+ siglisteners.append(siglistener)
+ currentThread().name = "Account sync %s" % accountname
+ account.syncrunner(siglistener=siglistener)
diff --git a/offlineimap/syncmaster.py b/offlineimap/syncmaster.py
index 2da8e3e..5a0a2fb 100644
--- a/offlineimap/syncmaster.py
+++ b/offlineimap/syncmaster.py
@@ -16,7 +16,6 @@
# 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 import mbnames
from offlineimap.threadutil import threadlist, InstanceLimitedThread, ExitNotifyThread
from offlineimap.accounts import SyncableAccount, SigListener
from threading import currentThread
@@ -33,11 +32,10 @@ def syncaccount(threads, config, accountname, siglisteners):
thread.setDaemon(1)
thread.start()
threads.add(thread)
-
+
def syncitall(accounts, config, siglisteners):
currentThread().setExitMessage('SYNC_WITH_TIMER_TERMINATE')
threads = threadlist()
- mbnames.init(config, accounts)
for accountname in accounts:
syncaccount(threads, config, accountname, siglisteners)
# Wait for the threads to finish.
--
1.7.1
More information about the OfflineIMAP-project
mailing list