summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbwarsaw2002-03-13 05:57:37 +0000
committerbwarsaw2002-03-13 05:57:37 +0000
commit8600d5cc3f9a51142fc274a79eea7d8048994485 (patch)
tree32d8d6132baf80556b505b0a707da52b3e15be76
parente3c2af7859aa84a2fda80c9728b04e7f8e965e2e (diff)
downloadmailman-8600d5cc3f9a51142fc274a79eea7d8048994485.tar.gz
mailman-8600d5cc3f9a51142fc274a79eea7d8048994485.tar.zst
mailman-8600d5cc3f9a51142fc274a79eea7d8048994485.zip
-rw-r--r--Mailman/Queue/BounceRunner.py1
-rw-r--r--Mailman/Queue/OutgoingRunner.py3
-rw-r--r--Mailman/Queue/Runner.py37
3 files changed, 11 insertions, 30 deletions
diff --git a/Mailman/Queue/BounceRunner.py b/Mailman/Queue/BounceRunner.py
index 295ea440c..5013b8e77 100644
--- a/Mailman/Queue/BounceRunner.py
+++ b/Mailman/Queue/BounceRunner.py
@@ -31,7 +31,6 @@ from Mailman.Logging.Syslog import syslog
class BounceRunner(Runner):
QDIR = mm_cfg.BOUNCEQUEUE_DIR
- CACHELISTS = 0
def _dispose(self, mlist, msg, msgdata):
outq = get_switchboard(mm_cfg.OUTQUEUE_DIR)
diff --git a/Mailman/Queue/OutgoingRunner.py b/Mailman/Queue/OutgoingRunner.py
index 0b3973999..681814a92 100644
--- a/Mailman/Queue/OutgoingRunner.py
+++ b/Mailman/Queue/OutgoingRunner.py
@@ -43,9 +43,6 @@ class OutgoingRunner(Runner):
# Maps mailing lists to (recip, msg) tuples
self._permfailures = {}
self._permfail_counter = 0
- # We never lock the lists, but we need to be sure that MailList
- # objects read from the cache are always fresh.
- self._freshen = 1
# We look this function up only at startup time
modname = 'Mailman.Handlers.' + mm_cfg.DELIVERY_MODULE
mod = __import__(modname)
diff --git a/Mailman/Queue/Runner.py b/Mailman/Queue/Runner.py
index ffc8900d1..0f5183d13 100644
--- a/Mailman/Queue/Runner.py
+++ b/Mailman/Queue/Runner.py
@@ -20,6 +20,7 @@
import random
import time
import traceback
+import weakref
from cStringIO import StringIO
from Mailman import mm_cfg
@@ -34,22 +35,14 @@ from Mailman.Logging.Syslog import syslog
class Runner:
- CACHELISTS = 1
-
def __init__(self, slice=None, numslices=1):
self._kids = {}
- self._cachelists = self.CACHELISTS
# Create our own switchboard. Don't use the switchboard cache because
# we want to provide slice and numslice arguments.
self._switchboard = Switchboard(self.QDIR, slice, numslices)
# Create the shunt switchboard
self._shunt = Switchboard(mm_cfg.SHUNTQUEUE_DIR)
self._stop = 0
- # Used by _open_list() to decide whether to freshen the state of any
- # MailList object retrieved from the cache. Most runners will
- # eventually lock their lists, which automatically reloads their
- # state. It's only non-locking runners that need to set this.
- self._freshen = 0
def stop(self):
self._stop = 1
@@ -62,11 +55,6 @@ class Runner:
# Once through the loop that processes all the files in
# the queue directory.
filecnt = self.__oneloop()
- # If the _freshen flag is set, then we evict all the
- # MailList objects from the cache so that their state will
- # be updated, the next time through the loop.
- if self._freshen:
- self._listcache.clear()
# Do the periodic work for the subclass. BAW: this
# shouldn't be called here. There should be one more
# _doperiodic() call at the end of the __oneloop() loop.
@@ -86,6 +74,7 @@ class Runner:
self._cleanup()
def __oneloop(self):
+ syslog('debug', '===== starting loop')
# First, list all the files in our queue directory.
# Switchboard.files() is guaranteed to hand us the files in FIFO
# order. Return an integer count of the number of files that were
@@ -123,6 +112,7 @@ class Runner:
self._doperiodic()
if self._shortcircuit():
break
+ syslog('debug', '===== finished loop (%s)', len(self._listcache))
return len(files)
def __onefile(self, msg, msgdata):
@@ -172,26 +162,22 @@ class Runner:
if keepqueued:
self._switchboard.enqueue(msg, msgdata)
- # Mapping of listnames to MailList instances
- _listcache = {}
+ # Mapping of listnames to MailList instances as a weak value dictionary.
+ _listcache = weakref.WeakValueDictionary()
def _open_list(self, listname):
- # Cache the opening of the list object given its name. The probably
- # is only a moderate win because when a list is locked, all its
- # attributes are re-read from the config.pck file. This may help more
- # when there's a real backing database.
- if self._cachelists:
- mlist = self._listcache.get(listname)
- else:
- mlist = None
+ # Cache the open list so that any use of the list within this process
+ # uses the same object. We use a WeakValueDictionary so that when the
+ # list is no longer necessary, its memory is freed.
+ mlist = self._listcache.get(listname)
if not mlist:
try:
mlist = MailList.MailList(listname, lock=0)
- if self._cachelists:
- self._listcache[listname] = mlist
except Errors.MMListError, e:
syslog('error', 'error opening list: %s\n%s', listname, e)
return None
+ else:
+ self._listcache[listname] = mlist
return mlist
def _log(self, exc):
@@ -210,7 +196,6 @@ class Runner:
any necessary resource deallocation. Its return value is irrelevant.
"""
Utils.reap(self._kids)
- self._listcache.clear()
def _dispose(self, mlist, msg, msgdata):
"""Dispose of a single message destined for a mailing list.