retry, use the message arrival time instead of the "first failed" time.
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.288 2006/02/08 16:10:46 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.289 2006/02/09 14:50:58 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
adding the default one. Similarly, if it contains a Reply-To: header, the
errors_reply_to option, if set, is not used.
+PH/19 When calculating a retry time, Exim used to measure the "time since
+ failure" by looking at the "first failed" field in the retry record. Now
+ it does not use this if it is later than than the arrival time of the
+ message. Instead it uses the arrival time. This makes for better
+ behaviour in cases where some deliveries succeed, thus re-setting the
+ "first failed" field. An example is a quota failure for a huge message
+ when small messages continue to be delivered. Without this change, the
+ "time since failure" will always be short, possible causing more frequent
+ delivery attempts for the huge message than are intended.
+
Exim version 4.60
-/* $Cambridge: exim/src/src/retry.c,v 1.6 2006/02/08 14:28:51 ph10 Exp $ */
+/* $Cambridge: exim/src/src/retry.c,v 1.7 2006/02/09 14:50:58 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
/* Compute how long this destination has been failing */
failing_interval = now - retry_record->first_failed;
+ DEBUG(D_retry) debug_printf("failing_interval=%d message_age=%d\n",
+ failing_interval, message_age);
+
+ /* If the message has been on the queue longer than the recorded time
+ of failure, use the message's age instead. This can happen when some
+ messages can be delivered and others cannot; a successful delivery will
+ reset the first_failed time, and this can lead to a failing message
+ being retried too often. */
+
+ if (message_age > failing_interval) failing_interval = message_age;
/* Search for the current retry rule. The cutoff time of the
last rule is handled differently to the others. The rule continues
This implements "timeout this rule if EITHER the host (or routing or
directing) has been failing for more than the maximum time, OR if the
- message has been on the queue for more than the maximum time." */
+ message has been on the queue for more than the maximum time."
+
+ February 2006: It is possible that this code is no longer needed
+ following the change to the retry calculation to use the message age if
+ it is larger than the time since first failure. It may be that the
+ expired flag is always set when the other conditions are met. However,
+ this is a small bit of code, and it does no harm to leave it in place,
+ just in case. */
if (received_time <= retry_record->first_failed &&
addr == endaddr && !retry_record->expired && rule != NULL)
#! /usr/bin/perl -w
-# $Cambridge: exim/test/runtest,v 1.2 2006/02/08 14:28:51 ph10 Exp $
+# $Cambridge: exim/test/runtest,v 1.3 2006/02/09 14:50:58 ph10 Exp $
###############################################################################
# This is the controlling script for the "new" test suite for Exim. It should #
# Time to retry may vary
s/time to retry = \S+/time to retry = tttt/;
s/retry record exists: age=\S+/retry record exists: age=ttt/;
+ s/failing_interval=\S+ message_age=\S+/failing_interval=ttt message_age=ttt/;
# Date/time in exim -bV output
s/\d\d-[A-Z][a-z]{2}-\d{4}\s\d\d:\d\d:\d\d/07-Mar-2000 12:21:52/g;
userx@test.ex
locking TESTSUITE/spool/db/retry.lockfile
retry for R:userx@test.ex = * 0 0
+failing_interval=ttt message_age=ttt
Writing retry data for R:userx@test.ex
first failed=dddd last try=dddd next try=+1 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<userx@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
locking TESTSUITE/spool/db/retry.lockfile
deleted retry information for R:test.ex
retry for R:userx@test.ex = * 0 0
+failing_interval=ttt message_age=ttt
Writing retry data for R:userx@test.ex
first failed=dddd last try=dddd next try=+1 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<userx@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
locking TESTSUITE/spool/db/retry.lockfile
deleted retry information for R:test.ex
retry for R:userx@test.ex = * 0 0
+failing_interval=ttt message_age=ttt
Writing retry data for R:userx@test.ex
first failed=dddd last try=dddd next try=+2 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<userx@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
usery@test.ex
locking TESTSUITE/spool/db/retry.lockfile
retry for R:usery@test.ex = * 0 0
+failing_interval=ttt message_age=ttt
Writing retry data for R:usery@test.ex
first failed=dddd last try=dddd next try=+1 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<usery@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
userx@test.ex
retry for R:userx@test.ex = * 0 0
+failing_interval=ttt message_age=ttt
Writing retry data for R:userx@test.ex
first failed=dddd last try=dddd next try=+1 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<userx@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
locking TESTSUITE/spool/db/retry.lockfile
deleted retry information for R:test.ex
retry for R:usery@test.ex = * 0 0
+failing_interval=ttt message_age=ttt
Writing retry data for R:usery@test.ex
first failed=dddd last try=dddd next try=+2 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<usery@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
userx@test.ex
deleted retry information for R:test.ex
retry for R:userx@test.ex = * 0 0
+failing_interval=ttt message_age=ttt
Writing retry data for R:userx@test.ex
first failed=dddd last try=dddd next try=+2 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<userx@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
x@y in "*"? yes (matched "*")
retry for R:x@y = * 0 0
dbfn_read: key=R:x@y
-on queue longer than maximum retry
+failing_interval=ttt message_age=ttt
Writing retry data for R:x@y
- first failed=dddd last try=dddd next try=+0 expired=0
+ first failed=dddd last try=dddd next try=+1 expired=1
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<x@y>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
dbfn_write: key=R:x@y
address match: subject=*@V4NET.0.0.0 pattern=*
*@V4NET.0.0.0 in "*"? yes (matched "*")
retry for T:V4NET.0.0.0:V4NET.0.0.0:1224 (y) = * 0 0
dbfn_read: key=T:V4NET.0.0.0:V4NET.0.0.0:1224
-on queue longer than maximum retry
+failing_interval=ttt message_age=ttt
Writing retry data for T:V4NET.0.0.0:V4NET.0.0.0:1224
- first failed=dddd last try=dddd next try=+0 expired=0
+ first failed=dddd last try=dddd next try=+1 expired=1
errno=dd more_errno=dd,A Network Error
dbfn_write: key=T:V4NET.0.0.0:V4NET.0.0.0:1224
timed out: all retries expired
TESTSUITE/test-mail/rmbox
locking TESTSUITE/spool/db/retry.lockfile
retry for T:TESTSUITE/test-mail/rmbox:x@test.ex = *@test.ex -22 0
+failing_interval=ttt message_age=ttt
Writing retry data for T:TESTSUITE/test-mail/rmbox:x@test.ex
first failed=dddd last try=dddd next try=+900 expired=0
errno=-22 more_errno=dd mailbox is full (MTA-imposed quota exceeded while writing to TESTSUITE/test-mail/rmbox)
userx@test.ex in "*"? yes (matched "*")
retry for T:userx@test.ex = * 0 0
dbfn_read: key=T:userx@test.ex
+failing_interval=ttt message_age=ttt
Writing retry data for T:userx@test.ex
first failed=dddd last try=dddd next try=+86400 expired=0
errno=-22 more_errno=dd mailbox is full (MTA-imposed quota exceeded while writing to tmp/MAILDIR.myhost.test.ex)
userx@test.ex in "*"? yes (matched "*")
retry for T:userx@test.ex = * 0 0
dbfn_read: key=T:userx@test.ex
+failing_interval=ttt message_age=ttt
Writing retry data for T:userx@test.ex
first failed=dddd last try=dddd next try=+86400 expired=0
errno=-22 more_errno=dd mailbox is full (MTA-imposed quota exceeded while writing to tmp/MAILDIR.myhost.test.ex)