Update of /cvsroot/mailman/mailman/Mailman/Queue
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15364
Modified Files:
Tag: Release_2_1-maint
OutgoingRunner.py
Log Message:
Much refactoring to improve bounce processing. The basic change moves the
queuing of bounce events out of the process's memory and into a 'bounce event'
file, essentially consisting of a stream of pickles. Every once in a while
the qrunner wakes up and processes the event file, which is named to be
specific to each qrunner instance. The actually processing is factored out
into a mixin class which is now subclassed by both the BounceRunner and
OutgoingRunner classes (since the latter has to handle SMTP rejects as
bounces).
Specific changes here include:
OutgoingRunner: Use BounceMixin as a base class. We can now get rid of the
whole _permfailures and _permfail_counter stuff since we'll just use the mixin
class as the basic logic for bounce handling.
_dispose(): Simplified since we can just use _queue_bounces() when a message
is rejected at SMTP time, although if that triggers a probe, the attached
message will be the one for which delivery was attempted since there really
isn't any bounce. Also, make this method handle probe bounces.
Index: OutgoingRunner.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Queue/OutgoingRunner.py,v
retrieving revision 2.15.2.2
retrieving revision 2.15.2.3
diff -u -d -r2.15.2.2 -r2.15.2.3
--- OutgoingRunner.py 22 Sep 2003 02:34:11 -0000 2.15.2.2
+++ OutgoingRunner.py 22 Feb 2004 22:37:45 -0000 2.15.2.3
@@ -1,4 +1,4 @@
-# Copyright (C) 2000-2003 by the Free Software Foundation, Inc.
+# Copyright (C) 2000-2004 by the Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -30,6 +30,7 @@
from Mailman import LockFile
from Mailman.Queue.Runner import Runner
from Mailman.Queue.Switchboard import Switchboard
+from Mailman.Queue.BounceRunner import BounceMixin
from Mailman.Logging.Syslog import syslog
# This controls how often _doperiodic() will try to deal with deferred
@@ -44,14 +45,12 @@
-class OutgoingRunner(Runner):
+class OutgoingRunner(Runner, BounceMixin):
QDIR = mm_cfg.OUTQUEUE_DIR
def __init__(self, slice=None, numslices=1):
Runner.__init__(self, slice, numslices)
- # Maps mailing lists to (recip, msg) tuples
- self._permfailures = {}
- self._permfail_counter = 0
+ BounceMixin.__init__(self)
# We look this function up only at startup time
modname = 'Mailman.Handlers.' + mm_cfg.DELIVERY_MODULE
mod = __import__(modname)
@@ -91,67 +90,46 @@
self.__logged = True
return True
except Errors.SomeRecipientsFailed, e:
- # The delivery module being used (SMTPDirect or Sendmail) failed
- # to deliver the message to one or all of the recipients.
- # Permanent failures should be registered (but registration
- # requires the list lock), and temporary failures should be
- # retried later.
- #
- # For permanent failures, make a copy of the message for bounce
- # handling. I'm not sure this is necessary, or the right thing to
- # do.
- if e.permfailures:
- pcnt = len(e.permfailures)
- msgcopy = copy.deepcopy(msg)
- self._permfailures.setdefault(mlist, []).extend(
- zip(e.permfailures, [msgcopy] * pcnt))
- # Move temporary failures to the qfiles/retry queue which will
- # occasionally move them back here for another shot at delivery.
- if e.tempfailures:
- now = time.time()
- recips = e.tempfailures
- last_recip_count = msgdata.get('last_recip_count', 0)
- deliver_until = msgdata.get('deliver_until', now)
- if len(recips) == last_recip_count:
- # We didn't make any progress, so don't attempt delivery
- # any longer. BAW: is this the best disposition?
- if now > deliver_until:
- return False
- else:
- # Keep trying to delivery this message for a while
- deliver_until = now + mm_cfg.DELIVERY_RETRY_PERIOD
- msgdata['last_recip_count'] = len(recips)
- msgdata['deliver_until'] = deliver_until
- msgdata['recips'] = recips
- self.__retryq.enqueue(msg, msgdata)
+ # Handle local rejects of probe messages differently.
+ if msgdata.get('probe_token'):
+ self._probe_bounce(mlist, msgdata['probe_token'])
+ else:
+ # Delivery failed at SMTP time for some or all of the
+ # recipients. Permanent failures are registered as bounces,
+ # but temporary failures are retried for later.
+ #
+ # BAW: msg is going to be the original message that failed
+ # delivery, not a bounce message. This may be confusing if
+ # this is what's sent to the user in the probe message. Maybe
+ # we should craft a bounce-like message containing information
+ # about the permanent SMTP failure?
+ self._queue_bounces(mlist.internal_name(), e.permfailures, msg)
+ # Move temporary failures to the qfiles/retry queue which will
+ # occasionally move them back here for another shot at
+ # delivery.
+ if e.tempfailures:
+ now = time.time()
+ recips = e.tempfailures
+ last_recip_count = msgdata.get('last_recip_count', 0)
+ deliver_until = msgdata.get('deliver_until', now)
+ if len(recips) == last_recip_count:
+ # We didn't make any progress, so don't attempt
+ # delivery any longer. BAW: is this the best
+ # disposition?
+ if now > deliver_until:
+ return False
+ else:
+ # Keep trying to delivery this message for a while
+ deliver_until = now + mm_cfg.DELIVERY_RETRY_PERIOD
+ msgdata['last_recip_count'] = len(recips)
+ msgdata['deliver_until'] = deliver_until
+ msgdata['recips'] = recips
+ self.__retryq.enqueue(msg, msgdata)
# We've successfully completed handling of this message
return False
- def _doperiodic(self):
- # Periodically try to acquire the list lock and clear out the
- # permanent failures.
- self._permfail_counter += 1
- if self._permfail_counter < DEAL_WITH_PERMFAILURES_EVERY:
- return
- self._handle_permfailures()
-
- def _handle_permfailures(self):
- # Reset the counter
- self._permfail_counter = 0
- # And deal with the deferred permanent failures.
- for mlist in self._permfailures.keys():
- try:
- mlist.Lock(timeout=mm_cfg.LIST_LOCK_TIMEOUT)
- except LockFile.TimeOutError:
- return
- try:
- for recip, msg in self._permfailures[mlist]:
- mlist.registerBounce(recip, msg)
- del self._permfailures[mlist]
- mlist.Save()
- finally:
- mlist.Unlock()
+ _doperiodic = BounceMixin._doperiodic
def _cleanup(self):
- self._handle_permfailures()
+ BounceMixin._cleanup(self)
Runner._cleanup(self)
_______________________________________________
Mailman-checkins mailing list
[EMAIL PROTECTED]
Unsubscribe: http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org