diff options
| author | Barry Warsaw | 2011-05-29 12:45:19 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2011-05-29 12:45:19 -0400 |
| commit | 521a179d309fac857fdbbe162d5db136c3ec3b1e (patch) | |
| tree | ec6e635e9c0f8a5bd655a254f9c346f1acb6dd8e /src/mailman/queue/outgoing.py | |
| parent | 0f760798fb2490a03041c42018afbd59749e6cbd (diff) | |
| download | mailman-521a179d309fac857fdbbe162d5db136c3ec3b1e.tar.gz mailman-521a179d309fac857fdbbe162d5db136c3ec3b1e.tar.zst mailman-521a179d309fac857fdbbe162d5db136c3ec3b1e.zip | |
Diffstat (limited to 'src/mailman/queue/outgoing.py')
| -rw-r--r-- | src/mailman/queue/outgoing.py | 160 |
1 files changed, 0 insertions, 160 deletions
diff --git a/src/mailman/queue/outgoing.py b/src/mailman/queue/outgoing.py deleted file mode 100644 index ed27f014c..000000000 --- a/src/mailman/queue/outgoing.py +++ /dev/null @@ -1,160 +0,0 @@ -# Copyright (C) 2000-2011 by the Free Software Foundation, Inc. -# -# This file is part of GNU Mailman. -# -# GNU Mailman is free software: you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) -# any later version. -# -# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along with -# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. - -"""Outgoing queue runner.""" - -import socket -import logging - -from datetime import datetime -from lazr.config import as_boolean, as_timedelta -from zope.component import getUtility - -from mailman.config import config -from mailman.interfaces.bounce import BounceContext, IBounceProcessor -from mailman.interfaces.mailinglist import Personalization -from mailman.interfaces.membership import ISubscriptionService -from mailman.interfaces.mta import SomeRecipientsFailed -from mailman.interfaces.pending import IPendings -from mailman.queue import Runner -from mailman.utilities.datetime import now -from mailman.utilities.modules import find_name - - -# This controls how often _do_periodic() will try to deal with deferred -# permanent failures. It is a count of calls to _do_periodic() -DEAL_WITH_PERMFAILURES_EVERY = 10 - -log = logging.getLogger('mailman.error') -smtp_log = logging.getLogger('mailman.smtp') - - - -class OutgoingRunner(Runner): - """The outgoing queue runner.""" - - def __init__(self, slice=None, numslices=1): - super(OutgoingRunner, self).__init__(slice, numslices) - # We look this function up only at startup time. - self._func = find_name(config.mta.outgoing) - # This prevents smtp server connection problems from filling up the - # error log. It gets reset if the message was successfully sent, and - # set if there was a socket.error. - self._logged = False - self._retryq = config.switchboards['retry'] - - def _dispose(self, mlist, msg, msgdata): - # See if we should retry delivery of this message again. - deliver_after = msgdata.get('deliver_after', datetime.fromtimestamp(0)) - if now() < deliver_after: - return True - # Calculate whether we should VERP this message or not. The results of - # this set the 'verp' key in the message metadata. - interval = int(config.mta.verp_delivery_interval) - if 'verp' in msgdata: - # Honor existing settings. - pass - # If personalization is enabled for this list and we've configured - # Mailman to always VERP personalized deliveries, then yes we VERP it. - # Also, if personalization is /not/ enabled, but - # verp_delivery_interval is set (and we've hit this interval), then - # again, this message should be VERP'd. Otherwise, no. - elif mlist.personalize != Personalization.none: - if as_boolean(config.mta.verp_personalized_deliveries): - msgdata['verp'] = True - elif interval == 0: - # Never VERP. - msgdata['verp'] = False - elif interval == 1: - # VERP every time. - msgdata['verp'] = True - else: - # VERP every 'interval' number of times. - msgdata['verp'] = (mlist.post_id % interval == 0) - try: - self._func(mlist, msg, msgdata) - self._logged = False - except socket.error: - # There was a problem connecting to the SMTP server. Log this - # once, but crank up our sleep time so we don't fill the error - # log. - port = int(config.mta.smtp_port) - if port == 0: - port = 'smtp' # Log this just once. - if not self._logged: - log.error('Cannot connect to SMTP server %s on port %s', - config.mta.smtp_host, port) - self._logged = True - return True - except SomeRecipientsFailed as error: - processor = getUtility(IBounceProcessor) - # BAW: msg is 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? - if 'probe_token' in msgdata: - # This is a failure of our local MTA to deliver to a probe - # message recipient. Register the bounce event for permanent - # failures. Start by grabbing and confirming (i.e. removing) - # the pendable record associated with this bounce token, - # regardless of what address was actually failing. - if len(error.permanent_failures) > 0: - pended = getUtility(IPendings).confirm( - msgdata['probe_token']) - # It's possible the token has been confirmed out of the - # database. Just ignore that. - if pended is not None: - member = getUtility(ISubscriptionService).get_member( - pended['member_id']) - processor.register( - mlist, member.address.email, msg, - BounceContext.probe) - 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. - for email in error.permanent_failures: - processor.register(mlist, email, msg, BounceContext.normal) - # Move temporary failures to the qfiles/retry queue which will - # occasionally move them back here for another shot at - # delivery. - if error.temporary_failures: - current_time = now() - recipients = error.temporary_failures - last_recip_count = msgdata.get('last_recip_count', 0) - deliver_until = msgdata.get('deliver_until', current_time) - if len(recipients) == last_recip_count: - # We didn't make any progress. If we've exceeded the - # configured retry period, log this failure and - # discard the message. - if current_time > deliver_until: - smtp_log.error('Discarding message with ' - 'persistent temporary failures: ' - '{0}'.format(msg['message-id'])) - return False - else: - # We made some progress, so keep trying to delivery - # this message for a while longer. - deliver_until = current_time + as_timedelta( - config.mta.delivery_retry_period) - msgdata['last_recip_count'] = len(recipients) - msgdata['deliver_until'] = deliver_until - msgdata['recipients'] = recipients - self._retryq.enqueue(msg, msgdata) - # We've successfully completed handling of this message. - return False |
