diff options
| author | bwarsaw | 2000-06-23 04:35:58 +0000 |
|---|---|---|
| committer | bwarsaw | 2000-06-23 04:35:58 +0000 |
| commit | a9a58042b6ac54e0d2d57882efdce7cd26123ccd (patch) | |
| tree | 583927d10d54c16f3144eb91a69d524c1cf7237b /Mailman | |
| parent | c7a89854238d675925e84fd9dae20d69a847c088 (diff) | |
| download | mailman-a9a58042b6ac54e0d2d57882efdce7cd26123ccd.tar.gz mailman-a9a58042b6ac54e0d2d57882efdce7cd26123ccd.tar.zst mailman-a9a58042b6ac54e0d2d57882efdce7cd26123ccd.zip | |
ArchiveMail(): First, extended the signature to take a msgdata
dictionary, which gets filled in with the child pid. This allows it
to be reaped by functions higher up in the call chain.
Second, and more importantly, be quite paranoid about the fork and
child processes. Make absolutely sure that the child process exits.
Wrap all the child code in try blocks so that no matter what, the lock
will get released (by calling unlock() with the unconditionally flag
set). If no exception occurs, the child will exit with status 0,
otherwise the traceback will be printed to stderr, a message
indicating which list has a corrupt archive is logged to logs/error,
and the child process will exit with status 1.
Extend the archive.lock to 1 hour.
Diffstat (limited to 'Mailman')
| -rw-r--r-- | Mailman/Archiver/Archiver.py | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/Mailman/Archiver/Archiver.py b/Mailman/Archiver/Archiver.py index b12aa77a7..db63331d9 100644 --- a/Mailman/Archiver/Archiver.py +++ b/Mailman/Archiver/Archiver.py @@ -22,8 +22,6 @@ mechanism (eg, pipermail) should be pointed to the right places, to do the archival. """ - -import sys import os import string import errno @@ -187,20 +185,27 @@ class Archiver: # # archiving in real time this is called from list.post(msg) # - def ArchiveMail(self, msg): + def ArchiveMail(self, msg, msgdata): """Store postings in mbox and/or pipermail archive, depending.""" # Fork so archival errors won't disrupt normal list delivery if mm_cfg.ARCHIVE_TO_MBOX == -1: return - if os.fork(): - return + pid = os.fork() + if pid: + # in the parent + kids = msgdata.get('_kids', {}) + kids[pid] = pid + msgdata['_kids'] = kids + return + # in the child + # # archive to builtin html archiver. first grab the archiver lock - lockfile = os.path.join(mm_cfg.LOCK_DIR, self._internal_name) + \ - '.archiver.lock' - lock = LockFile.LockFile(lockfile, lifetime=60*5) - lock.lock() try: try: + lockfile = os.path.join(mm_cfg.LOCK_DIR, + self.internal_name()+'.archiver.lock') + lock = LockFile.LockFile(lockfile, lifetime=mm_cfg.hours(1)) + lock.lock() if mm_cfg.ARCHIVE_TO_MBOX in [1, 2]: self.__archive_to_mbox(msg) if mm_cfg.ARCHIVE_TO_MBOX == 1: @@ -208,6 +213,7 @@ class Archiver: os._exit(0) # from this point on, we're doing all the expensive archiving # work. + syslog('error', 'starting to archive') txt = msg.unixfrom for h in msg.headers: txt = txt + h @@ -221,7 +227,7 @@ class Archiver: # should we use the internal or external archiver? private_p = self.archive_private if mm_cfg.PUBLIC_EXTERNAL_ARCHIVER and not private_p: - self.ExternalArchive(mm_cfg.PUBLIC_EXTERNAL_ARCHIVER, txt) + self.ExternalArchive(mm_cfg.PUBLIC_EXTERNAL_ARCHIVER, txt) elif mm_cfg.PRIVATE_EXTERNAL_ARCHIVER and private_p: self.ExternalArchive(mm_cfg.PRIVATE_EXTERNAL_ARCHIVER, txt) else: @@ -232,17 +238,16 @@ class Archiver: h.processUnixMailbox(f, HyperArch.Article) h.close() f.close() - except: - traceback.print_exc(file=sys.stderr) - finally: - # it's still possible to take a long time to run the archiver :( - try: - lock.unlock() - except LockFile.NotLockedError: - pass - # need this or we'll never see the error messages! - sys.stderr.flush() + finally: + # It's still possible to take a long time to run the archiver + lock.unlock(unconditionally=1) + syslog('error', 'finished archiving') os._exit(0) + except: + traceback.print_exc() + syslog('error', 'CORRUPT ARCHIVE FOR LIST: %s' % + self.internal_name()) + os._exit(1) # # called from MailList.MailList.Save() |
