summaryrefslogtreecommitdiff
path: root/Mailman/MailList.py
diff options
context:
space:
mode:
authorbwarsaw2002-04-01 16:31:25 +0000
committerbwarsaw2002-04-01 16:31:25 +0000
commitd05d2eb75b106c0302e53961a92c65b17aea7f7b (patch)
treeea7c19e8bd2d9fecf5fd8ef535a30735a93f54d9 /Mailman/MailList.py
parent03746ddd239e39255fabb84c08e649325572b864 (diff)
downloadmailman-d05d2eb75b106c0302e53961a92c65b17aea7f7b.tar.gz
mailman-d05d2eb75b106c0302e53961a92c65b17aea7f7b.tar.zst
mailman-d05d2eb75b106c0302e53961a92c65b17aea7f7b.zip
Make it much cheaper to call Load(), especially when the state hasn't
changed since the last Load(). This means it will be cost effective to reload the state when necessary in qrunners which don't lock the list (e.g. OutgoingRunner). Specifically, InitTempVars(): Set a temporary timestamp attribute, which gets the mtime of the config.pck file upon successful load. __save(): When we save the file, set the timestamp to the file's mtime (we just saved it so it must be up-to-date -- since this is done with the list lock acquired, there shouldn't be a race). __load(): If the file's mtime is <= the current timestamp, then we've got the most current state. This method can now return (None, None) meaning we didn't need to load anything. Load(): Watch for dict is None and e is None, meaning we didn't need to load anything.
Diffstat (limited to 'Mailman/MailList.py')
-rw-r--r--Mailman/MailList.py25
1 files changed, 20 insertions, 5 deletions
diff --git a/Mailman/MailList.py b/Mailman/MailList.py
index 2dcd4c116..28e60ac39 100644
--- a/Mailman/MailList.py
+++ b/Mailman/MailList.py
@@ -223,6 +223,10 @@ class MailList(MailCommandHandler, HTMLFormatter, Deliverer, ListAdmin,
#
def InitTempVars(self, name):
"""Set transient variables of this and inherited classes."""
+ # The timestamp is set whenever we load the state from disk. If our
+ # timestamp is newer than the modtime of the config.pck file, we don't
+ # need to reload, otherwise... we do.
+ self.__timestamp = 0
self.__lock = LockFile.LockFile(
os.path.join(mm_cfg.LOCK_DIR, name or '<site>') + '.lock',
# TBD: is this a good choice of lifetime?
@@ -447,6 +451,8 @@ class MailList(MailCommandHandler, HTMLFormatter, Deliverer, ListAdmin,
except OSError, e:
if e.errno <> errno.ENOENT: raise
os.rename(fname_tmp, fname)
+ # Reset the timestamp
+ self.__timestamp = os.path.getmtime(fname)
def Save(self):
# Refresh the lock, just to let other processes know we're still
@@ -486,7 +492,11 @@ class MailList(MailCommandHandler, HTMLFormatter, Deliverer, ListAdmin,
elif dbfile.endswith('.pck') or dbfile.endswith('.pck.last'):
loadfunc = cPickle.load
else:
- assert 0
+ assert 0, 'Bad database file name'
+ mtime = os.path.getmtime(dbfile)
+ if mtime <= self.__timestamp:
+ # File is not newer
+ return None, None
try:
fp = open(dbfile)
except IOError, e:
@@ -502,6 +512,8 @@ class MailList(MailCommandHandler, HTMLFormatter, Deliverer, ListAdmin,
return None, e
finally:
fp.close()
+ # Update timestamp
+ self.__timestamp = mtime
return dict, None
def Load(self, check_version=1):
@@ -521,10 +533,13 @@ class MailList(MailCommandHandler, HTMLFormatter, Deliverer, ListAdmin,
for file in (pfile, plast, dfile, dlast):
dict, e = self.__load(file)
if dict is None:
- # Had problems with this file; log it and try the next one.
- syslog('error',
- '%s config file was corrupt, trying fallback: %s',
- self.internal_name(), file)
+ if e is not None:
+ # Had problems with this file; log it and try the next one.
+ syslog('error', "couldn't load config file %s\n%s",
+ file, e)
+ else:
+ # We already have the most up-to-date state
+ return
else:
break
else: