threading: minor improvements

Factorize string, enhance comments and minor code improvements.

Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Nicolas Sebrecht 2016-05-17 03:53:09 +02:00
parent f93b0963fa
commit 83539f8601
4 changed files with 27 additions and 12 deletions

View File

@ -351,11 +351,12 @@ class SyncableAccount(Account):
"[%s]"% (localfolder, localfolder.repository)) "[%s]"% (localfolder, localfolder.repository))
continue # Ignore filtered folder continue # Ignore filtered folder
if not globals.options.singlethreading: if not globals.options.singlethreading:
thread = InstanceLimitedThread(\ thread = InstanceLimitedThread(
instancename = 'FOLDER_' + self.remoterepos.getname(), instancename = 'FOLDER_' + self.remoterepos.getname(),
target = syncfolder, target = syncfolder,
name = "Folder %s [acc: %s]"% (remotefolder.getexplainedname(), self), name = "Folder %s [acc: %s]"% (remotefolder.getexplainedname(), self),
args = (self, remotefolder, quick)) args = (self, remotefolder, quick)
)
thread.start() thread.start()
folderthreads.append(thread) folderthreads.append(thread)
else: else:

View File

@ -871,11 +871,12 @@ class BaseFolder(object):
# exceptions are caught in copymessageto() # exceptions are caught in copymessageto()
if self.suggeststhreads() and not globals.options.singlethreading: if self.suggeststhreads() and not globals.options.singlethreading:
self.waitforthread() self.waitforthread()
thread = threadutil.InstanceLimitedThread(\ thread = threadutil.InstanceLimitedThread(
self.getcopyinstancelimit(), self.getcopyinstancelimit(),
target = self.copymessageto, target = self.copymessageto,
name = "Copy message from %s:%s" % (self.repository, self), name = "Copy message from %s:%s" % (self.repository, self),
args = (uid, dstfolder, statusfolder)) args = (uid, dstfolder, statusfolder)
)
thread.start() thread.start()
threads.append(thread) threads.append(thread)
else: else:

View File

@ -35,6 +35,7 @@ from offlineimap.repository import Repository
import traceback import traceback
import collections import collections
ACCOUNT_LIMITED_THREAD_NAME = 'MAX_ACCOUNTS'
def syncitall(list_accounts, config): def syncitall(list_accounts, config):
"""The target when in multithreading mode for running accounts threads.""" """The target when in multithreading mode for running accounts threads."""
@ -44,7 +45,7 @@ def syncitall(list_accounts, config):
# Start a new thread per account and store it in the collection. # Start a new thread per account and store it in the collection.
account = accounts.SyncableAccount(config, accountname) account = accounts.SyncableAccount(config, accountname)
thread = threadutil.InstanceLimitedThread( thread = threadutil.InstanceLimitedThread(
instancename = 'ACCOUNTLIMIT', instancename = ACCOUNT_LIMITED_THREAD_NAME,
target = account.syncrunner, target = account.syncrunner,
name = "Account sync %s"% accountname name = "Account sync %s"% accountname
) )
@ -287,18 +288,27 @@ class OfflineImap:
if socktimeout > 0: if socktimeout > 0:
socket.setdefaulttimeout(socktimeout) socket.setdefaulttimeout(socktimeout)
threadutil.initInstanceLimit('ACCOUNTLIMIT', threadutil.initInstanceLimit(
config.getdefaultint('general', 'maxsyncaccounts', 1)) ACCOUNT_LIMITED_THREAD_NAME,
config.getdefaultint('general', 'maxsyncaccounts', 1)
)
for reposname in config.getsectionlist('Repository'): for reposname in config.getsectionlist('Repository'):
# XXX: We are likely lying around. If we must use at most n
# connections for a remote IMAP server, why do we allow twice this
# number? The max connections number is used by both the FOLDER_ and
# the MSGCOPY_ prefixes!
for instancename in ["FOLDER_" + reposname, for instancename in ["FOLDER_" + reposname,
"MSGCOPY_" + reposname]: "MSGCOPY_" + reposname]:
if options.singlethreading: if options.singlethreading:
threadutil.initInstanceLimit(instancename, 1) threadutil.initInstanceLimit(instancename, 1)
else: else:
threadutil.initInstanceLimit(instancename, threadutil.initInstanceLimit(
config.getdefaultint('Repository ' + reposname, instancename,
'maxconnections', 2)) config.getdefaultint(
'Repository ' + reposname,
'maxconnections', 2)
)
self.config = config self.config = config
return (options, args) return (options, args)

View File

@ -224,8 +224,10 @@ class ExitNotifyThread(Thread):
instancelimitedsems = {} instancelimitedsems = {}
def initInstanceLimit(instancename, instancemax): def initInstanceLimit(instancename, instancemax):
"""Initialize the instance-limited thread implementation to permit """Initialize the instance-limited thread implementation.
up to intancemax threads with the given instancename."""
Run up to intancemax threads for the given instancename. This allows
to honor maxsyncaccounts and maxconnections."""
global instancelimitedsems global instancelimitedsems
@ -235,6 +237,7 @@ def initInstanceLimit(instancename, instancemax):
class InstanceLimitedThread(ExitNotifyThread): class InstanceLimitedThread(ExitNotifyThread):
def __init__(self, instancename, *args, **kwargs): def __init__(self, instancename, *args, **kwargs):
# XXX: this is not a instance name, is it?
self.instancename = instancename self.instancename = instancename
super(InstanceLimitedThread, self).__init__(*args, **kwargs) super(InstanceLimitedThread, self).__init__(*args, **kwargs)