diff options
| author | bwarsaw | 2002-04-01 16:31:25 +0000 |
|---|---|---|
| committer | bwarsaw | 2002-04-01 16:31:25 +0000 |
| commit | d05d2eb75b106c0302e53961a92c65b17aea7f7b (patch) | |
| tree | ea7c19e8bd2d9fecf5fd8ef535a30735a93f54d9 | |
| parent | 03746ddd239e39255fabb84c08e649325572b864 (diff) | |
| download | mailman-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.
| -rw-r--r-- | Mailman/MailList.py | 25 |
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: |
