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 dd11682f1f1f053d0b811720cc2bc624bcd25363..cc82287fe838e419d534ae31ff6f2d49ea26b0f3 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
 -------------------------------------------
 
 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.
 
       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
 
 
 Exim version 4.60
index 2a5516003078797f3a64840d829c815af032b336..eb4cd46cc18900189a3b0d20fe10295615ef037f 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    *
 
 /*************************************************
 *     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;
         /* 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
 
         /* 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
 
         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)
 
         if (received_time <= retry_record->first_failed &&
             addr == endaddr && !retry_record->expired && rule != NULL)
index acff149af00169ef0f3f4b52751a04f6f68e1092..2210cba3b66af6d3c06d6162db1c9d9dec09a470 100755 (executable)
@@ -1,6 +1,6 @@
 #! /usr/bin/perl -w
 
 #! /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 #
 
 ###############################################################################
 # 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/;
   # 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;
 
   # 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 3692e95741baaa84d35e790f865581ce6752584d..f7bc3f6357b9e3031b751bb71ec6685a02e1a2e0 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
 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
 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
 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
 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
 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
 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 dd36d0267d3b223e632d37dca1a1febc1e2cac3f..2756de19a43baefc6e68ca13c97bef739f0a9711 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
 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
 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
 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
 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
 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
 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 fcb73193a27b883d0334e235ecca16d0a7c0d478..ca5e45e6073abddb89ee13952a0a2469f6feef6b 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
 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
 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=*
   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
 *@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
 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
   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 bed589de6d8c8a8969e37ceac54f1e52c2b97bf6..406de192ccc05269e983fedbeb1943db159a3267 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
 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)
 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 8a8c8ad3bfb75d13732b320fe0505e792ce80f84..87fc73f8d8b678ba25048e91be3c28a2951e6e6b 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
 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)
 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
 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)
 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)