If a message is older than the "first failed" time when computing a
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Thu, 9 Feb 2006 14:50:58 +0000 (14:50 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Thu, 9 Feb 2006 14:50:58 +0000 (14:50 +0000)
retry, use the message arrival time instead of the "first failed" time.

doc/doc-txt/ChangeLog
src/src/retry.c
test/runtest
test/stderr/0357
test/stderr/0358
test/stderr/0388
test/stderr/0529
test/stderr/5005

index dd11682..cc82287 100644 (file)
@@ -1,4 +1,4 @@
-$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
 -------------------------------------------
@@ -106,6 +106,16 @@ PH/18 If quota_warn_message contains a From: header, Exim now refrains from
       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
index 2a55160..eb4cd46 100644 (file)
@@ -1,4 +1,4 @@
-/* $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    *
@@ -684,6 +684,16 @@ for (i = 0; i < 3; i++)
         /* 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
@@ -738,7 +748,14 @@ for (i = 0; i < 3; i++)
 
         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)
index acff149..2210cba 100755 (executable)
@@ -1,6 +1,6 @@
 #! /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 #
@@ -417,6 +417,7 @@ while(<IN>)
   # 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;
index 3692e95..f7bc3f6 100644 (file)
@@ -37,6 +37,7 @@ Deferred addresses:
 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
@@ -85,6 +86,7 @@ userx@test.ex
 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
@@ -134,6 +136,7 @@ userx@test.ex
 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
index dd36d02..2756de1 100644 (file)
@@ -47,11 +47,13 @@ Deferred addresses:
 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
@@ -117,12 +119,14 @@ usery@test.ex
 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
index fcb7319..ca5e45e 100644 (file)
@@ -145,9 +145,9 @@ y in "*"? yes (matched "*")
 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=*
@@ -155,9 +155,9 @@ V4NET.0.0.0 in "*"? yes (matched "*")
 *@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
index bed589d..406de19 100644 (file)
@@ -38,6 +38,7 @@ Deferred addresses:
 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)
index 8a8c8ad..87fc73f 100644 (file)
@@ -486,6 +486,7 @@ test.ex in "*"? yes (matched "*")
 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)
@@ -652,6 +653,7 @@ test.ex in "*"? yes (matched "*")
 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)