summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbwarsaw2000-05-09 20:29:51 +0000
committerbwarsaw2000-05-09 20:29:51 +0000
commit50130ff56272cc77f74a6cbbdd6d279d96015020 (patch)
treec090c8802f3358020aa40dce45a7eb692f839782
parentc70865202b9b8bc576b710b9cba894c65975aeaf (diff)
downloadmailman-50130ff56272cc77f74a6cbbdd6d279d96015020.tar.gz
mailman-50130ff56272cc77f74a6cbbdd6d279d96015020.tar.zst
mailman-50130ff56272cc77f74a6cbbdd6d279d96015020.zip
Changes to allow more control over list locking. This is used in
scripts/post and other places to catch lock timeouts in a way that can be reasonably handled. Specifically, __init__(): Don't pass the lock flag to InitTempVars(). Instead, use it directly in the constructor. InitTempVars(): This doesn't get a lock argument anymore, but it still creates the lock file. Also, the withlogging argument takes its default from mm_cfg.LIST_LOCK_DEBUGGING so it's easier to turn on lock debugging globally. Load(): No longer lock the database here. Load() is essentially used internally anyway. Post(): Removed. All email generated internally is sent directly via the HandlerAPI interface. Lock(): Now has a timeout argument, which is passed to the underlying LockFile.lock() method.
-rw-r--r--Mailman/MailList.py43
1 files changed, 20 insertions, 23 deletions
diff --git a/Mailman/MailList.py b/Mailman/MailList.py
index 45dd5ae00..beb4c9691 100644
--- a/Mailman/MailList.py
+++ b/Mailman/MailList.py
@@ -64,10 +64,18 @@ class MailList(MailCommandHandler, HTMLFormatter, Deliverer, ListAdmin,
Archiver, Digester, SecurityManager, Bouncer, GatewayManager,
Autoresponder):
def __init__(self, name=None, lock=1):
+ # No timeout by default. If you want to timeout, open the list
+ # unlocked, then lock explicitly.
MailCommandHandler.__init__(self)
- self.InitTempVars(name, lock)
- if name:
- self.Load()
+ self.InitTempVars(name)
+ if name:
+ if lock:
+ self.Lock()
+ try:
+ self.Load()
+ except Errors.MMListError:
+ self.Unlock()
+ raise
def __del__(self):
try:
@@ -273,14 +281,13 @@ class MailList(MailCommandHandler, HTMLFormatter, Deliverer, ListAdmin,
return None
return string.lower(matches[0])
- def InitTempVars(self, name, lock):
+ def InitTempVars(self, name):
"""Set transient variables of this and inherited classes."""
- self.__createlock_p = lock
self.__lock = LockFile.LockFile(
os.path.join(mm_cfg.LOCK_DIR, name or '<site>') + '.lock',
# TBD: is this a good choice of lifetime?
lifetime = mm_cfg.LIST_LOCK_LIFETIME,
- withlogging=1)
+ withlogging = mm_cfg.LIST_LOCK_DEBUGGING)
self._internal_name = name
self._ready = 0
self._log_files = {} # 'class': log_file_obj
@@ -850,6 +857,11 @@ it will not be changed."""),
os.rename(fname_tmp, fname)
def Save(self):
+ # Refresh the lock, just to let other processes know we're still
+ # interested in it. This will raise a NotLockedError if we don't have
+ # the lock (which is a serious problem!). TBD: do we need to be more
+ # defensive?
+ self.__lock.refresh()
# If more than one client is manipulating the database at once, we're
# pretty hosed. That's a good reason to make this a daemon not a
# program.
@@ -870,15 +882,9 @@ it will not be changed."""),
self.CheckHTMLArchiveDir()
def Load(self, check_version=1):
- if self.__createlock_p:
- try:
- self.Lock()
- except LockFile.AlreadyLockedError:
- pass
try:
file = open(os.path.join(self._full_path, 'config.db'), 'r')
except IOError, e:
- self.Unlock()
raise Errors.MMUnknownListError, e
try:
dict = marshal.load(file)
@@ -887,7 +893,6 @@ it will not be changed."""),
raise Errors.MMCorruptListDatabaseError(
"List's config.db did not unmarshal into a dictionary")
except (EOFError, ValueError, TypeError), e:
- self.Unlock()
raise Errors.MMCorruptListDatabaseError, e
for key, value in dict.items():
setattr(self, key, value)
@@ -1326,19 +1331,11 @@ it will not be changed."""),
return line
return 0
- # msg should be an Message.Message object.
- def Post(self, msg):
- self.IsListInitialized()
- # TBD: this is bogus and will later be configurable
- import Mailman.Handlers.HandlerAPI
- Mailman.Handlers.HandlerAPI.DeliverToList(self, msg)
- self.Save()
-
def Locked(self):
return self.__lock.locked()
- def Lock(self):
- self.__lock.lock()
+ def Lock(self, timeout=0):
+ self.__lock.lock(timeout)
def Unlock(self):
try: