Fix retry key bug for pipe, file, or autoreply deliveries.
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Wed, 8 Feb 2006 14:28:51 +0000 (14:28 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Wed, 8 Feb 2006 14:28:51 +0000 (14:28 +0000)
15 files changed:
doc/doc-txt/ChangeLog
src/src/deliver.c
src/src/readconf.c
src/src/retry.c
test/aux-fixed/setrt [new file with mode: 0644]
test/confs/0529 [new file with mode: 0644]
test/log/0529 [new file with mode: 0644]
test/runtest
test/scripts/0000-Basic/0529 [new file with mode: 0644]
test/stderr/0357
test/stderr/0358
test/stderr/0388
test/stderr/0476
test/stderr/0529 [new file with mode: 0644]
test/stderr/5005

index d914efb..f8f046b 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.286 2006/02/07 16:36:25 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.287 2006/02/08 14:28:51 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -98,6 +98,10 @@ PH/16 As discussed on the list in Nov/Dec: Exim no longer looks at the
       address records were *not* found in the additional section, the port
       values from the SRV records were lost.
 
+PH/17 If a delivery to a pipe, file, or autoreply was deferred, Exim was not
+      using the correct key (the original address) when searching the retry
+      rules in order to find which one to use for generating the retry hint.
+
 
 
 Exim version 4.60
index 9351d45..dbec42e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/deliver.c,v 1.26 2006/02/07 11:19:00 ph10 Exp $ */
+/* $Cambridge: exim/src/src/deliver.c,v 1.27 2006/02/08 14:28:51 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -2250,10 +2250,12 @@ while (addr_local != NULL)
 
         DEBUG(D_retry)
           {
-          debug_printf("retry record exists: age=%d (max=%d)\n",
-            (int)(now - retry_record->time_stamp), retry_data_expire);
-          debug_printf("  time to retry = %d expired = %d\n",
-            (int)(now - retry_record->next_try), retry_record->expired);
+          debug_printf("retry record exists: age=%s ",
+            readconf_printtime(now - retry_record->time_stamp));
+          debug_printf("(max %s)\n", readconf_printtime(retry_data_expire));
+          debug_printf("  time to retry = %s expired = %d\n",
+            readconf_printtime(retry_record->next_try - now),
+            retry_record->expired);
           }
 
         if (queue_running && !deliver_force)
@@ -2282,9 +2284,18 @@ while (addr_local != NULL)
               for (last_rule = retry->rules;
                    last_rule->next != NULL;
                    last_rule = last_rule->next);
+              DEBUG(D_deliver|D_retry)
+                debug_printf("now=%d received_time=%d diff=%d timeout=%d\n",
+                  (int)now, received_time, (int)now - received_time,
+                  last_rule->timeout);
               if (now - received_time > last_rule->timeout) ok = TRUE;
               }
-            else ok = TRUE;    /* No rule => timed out */
+            else
+              {
+              DEBUG(D_deliver|D_retry)
+                debug_printf("no retry rule found: assume timed out\n");
+              ok = TRUE;    /* No rule => timed out */
+              }
 
             DEBUG(D_deliver|D_retry)
               {
index b860b96..5623b87 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/readconf.c,v 1.17 2006/02/07 11:19:00 ph10 Exp $ */
+/* $Cambridge: exim/src/src/readconf.c,v 1.18 2006/02/08 14:28:51 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -2011,6 +2011,12 @@ readconf_printtime(int t)
 int s, m, h, d, w;
 uschar *p = time_buffer;
 
+if (t < 0)
+  {
+  *p++ = '-';
+  t = -t;
+  }
+
 s = t % 60;
 t /= 60;
 m = t % 60;
index b54bb7d..2a55160 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/retry.c,v 1.5 2006/02/07 11:19:00 ph10 Exp $ */
+/* $Cambridge: exim/src/src/retry.c,v 1.6 2006/02/08 14:28:51 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -46,8 +46,17 @@ if (retry != NULL && retry->rules != NULL)
   for (last_rule = retry->rules;
        last_rule->next != NULL;
        last_rule = last_rule->next);
+  DEBUG(D_transport|D_retry)
+    debug_printf("now=%d received_time=%d diff=%d timeout=%d\n",
+      (int)now, received_time, (int)(now - received_time),
+      last_rule->timeout);
   address_timeout = (now - received_time > last_rule->timeout);
   }
+else
+  {
+  DEBUG(D_transport|D_retry)
+    debug_printf("no retry rule found: assume timed out\n");
+  }
 
 return address_timeout;
 }
@@ -340,23 +349,38 @@ retry_config *
 retry_find_config(uschar *key, uschar *alternate, int basic_errno,
   int more_errno)
 {
-int replace;
+int replace = 0;
 uschar *use_key, *use_alternate;
 uschar *colon = Ustrchr(key, ':');
 retry_config *yield;
 
-/* If there's a colon in the key, temporarily replace it with
-a zero to terminate the string there. */
+/* If there's a colon in the key, there are two possibilities:
+
+(1) This is a key for a host, ip address, and possibly port, in the format
+
+      hostname:ip+port
+
+    In this case, we temporarily replace the colon with a zero, to terminate
+    the string after the host name.
+
+(2) This is a key for a pipe, file, or autoreply delivery, in the format
+
+      pipe-or-file-or-auto:x@y
+
+    where x@y is the original address that provoked the delivery. The pipe or
+    file or auto will start with | or / or >, whereas a host name will start
+    with a letter or a digit. In this case we want to use the original address
+    to search for a retry rule. */
 
 if (colon != NULL)
   {
-  replace = ':';
-  }
-else
-  {
-  colon = key + Ustrlen(key);
-  replace = 0;
+  if (isalnum(*key))
+    replace = ':';
+  else
+    key = Ustrrchr(key, ':') + 1;   /* Take from the last colon */
   }
+
+if (replace == 0) colon = key + Ustrlen(key);
 *colon = 0;
 
 /* Sort out the keys */
@@ -619,10 +643,12 @@ for (i = 0; i < 3; i++)
         DEBUG(D_retry)
           {
           if ((rti->flags & rf_host) != 0)
-            debug_printf("retry for %s (%s) = %s\n", rti->key,
-              addr->domain, retry->pattern);
+            debug_printf("retry for %s (%s) = %s %d %d\n", rti->key,
+              addr->domain, retry->pattern, retry->basic_errno,
+              retry->more_errno);
           else
-            debug_printf("retry for %s = %s\n", rti->key, retry->pattern);
+            debug_printf("retry for %s = %s %d %d\n", rti->key, retry->pattern,
+              retry->basic_errno, retry->more_errno);
           }
 
         /* Set up the message for the database retry record. Because DBM
diff --git a/test/aux-fixed/setrt b/test/aux-fixed/setrt
new file mode 100644 (file)
index 0000000..8504650
--- /dev/null
@@ -0,0 +1,39 @@
+# This is a little perl script that adjusts the "received" time in a -H file,
+# so that retry timeouts etc can be more easily tested. Its arguments are:
+#
+# (1) The number of the message on the queue whose time is to be adjusted; 1 
+#     for the first message, 2 for the second, etc.
+#
+# (2) A positive or negative number by which to adjust the received time.
+
+$fileno = $ARGV[0] - 1;
+$adjust = $ARGV[1];
+
+opendir(DIR, "spool/input");
+while (($_ = readdir(DIR))) { push(@files, $_) if /.*-H$/; }
+closedir(DIR);    
+
+@files = sort @files;
+
+open(IN, "spool/input/$files[$fileno]") || 
+  die "can't open spool/input/$files[$fileno]";
+
+open(OUT, ">test-H");
+
+$_ = <IN>; print OUT;
+$_ = <IN>; print OUT;
+$_ = <IN>; print OUT;
+$_ = <IN>;
+($rtime,$rest) = $_ =~ /^(\d+)(.*)/;
+$rtime += $adjust;
+print OUT "$rtime$rest\n";
+print OUT while (<IN>);
+
+close(IN);
+close(OUT);
+
+rename("test-H", "spool/input/$files[$fileno]") || die "rename failed\n";
+
+exit(0);
+
+# End
diff --git a/test/confs/0529 b/test/confs/0529
new file mode 100644 (file)
index 0000000..247f745
--- /dev/null
@@ -0,0 +1,44 @@
+# Exim test configuration 0529
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+rfc1413_query_timeout = 0s
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+
+
+# ----- Routers -----
+
+begin routers
+
+r1:
+  driver = redirect
+  data = DIR/test-mail/rmbox
+  file_transport = t1
+
+
+# ----- Transports -----
+
+begin transports
+
+t1:
+  driver = appendfile
+  quota = 1
+  user = CALLER
+
+
+# ----- Retry -----
+
+begin retry
+
+*@test.ex        quota_7d
+*@test.ex        quota       F,2h,15m; F,3d,1h
+*                *           F,2h,15m; G,16h,1h,1.5; F,4d,6h
+
+# End
diff --git a/test/log/0529 b/test/log/0529
new file mode 100644 (file)
index 0000000..2e56375
--- /dev/null
@@ -0,0 +1,5 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 == TESTSUITE/test-mail/rmbox <x@test.ex> R=r1 T=t1 defer (-22): mailbox is full (MTA-imposed quota exceeded while writing to TESTSUITE/test-mail/rmbox)
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 10HmaX-0005vi-00 == TESTSUITE/test-mail/rmbox <x@test.ex> R=r1 T=t1 defer (-52): Retry time not yet reached
+1999-03-02 09:44:33 End queue run: pid=pppp
index 92bbe80..acff149 100755 (executable)
@@ -1,6 +1,6 @@
 #! /usr/bin/perl -w
 
-# $Cambridge: exim/test/runtest,v 1.1 2006/02/06 16:07:10 ph10 Exp $
+# $Cambridge: exim/test/runtest,v 1.2 2006/02/08 14:28:51 ph10 Exp $
 
 ###############################################################################
 # This is the controlling script for the "new" test suite for Exim. It should #
@@ -406,16 +406,17 @@ while(<IN>)
   # Date/time in mbx mailbox files
   s/\d\d-\w\w\w-\d\d\d\d\s\d\d:\d\d:\d\d\s[-+]\d\d\d\d,/06-Sep-1999 15:52:48 +0100,/gx;
 
-  # Date/time in debugging output for writing retry records
+  # Dates/times in debugging output for writing retry records
   if (/^  first failed=(\d+) last try=(\d+) next try=(\d+) (.*)$/)
     {
     my($next) = $3 - $2;
     $_ = "  first failed=dddd last try=dddd next try=+$next $4\n";
     }
+  s/^now=\d+ received_time=\d+ diff=\d+ timeout=(\d+)/now=tttt received_time=tttt diff=tttt timeout=$1/;
 
   # Time to retry may vary
-  s/time to retry = -\d+/time to retry = -ddddd/;
-  s/retry record exists: age=\d/retry record exists: age=d/;
+  s/time to retry = \S+/time to retry = tttt/;
+  s/retry record exists: age=\S+/retry record exists: 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;
@@ -1581,7 +1582,8 @@ if (/^(cat)?write\s+(\S+)(?:\s+(.*))?\s*$/)
 
 # The "client" and "client-ssl" commands run a script-driven program that plays
 # the part of an email client. We also have the availability of running Perl
-# for doing one-off special things.
+# for doing one-off special things. Note that all these commands expect stdin
+# data to be supplied.
 
 if (/^client/ || /^client-ssl/ || /^(sudo\s+)?perl\b/)
   {
diff --git a/test/scripts/0000-Basic/0529 b/test/scripts/0000-Basic/0529
new file mode 100644 (file)
index 0000000..3809cde
--- /dev/null
@@ -0,0 +1,10 @@
+# retries for quota exceeded when routed to a file
+#
+exim -d-all+retry -odi x@test.ex
+****
+# Adjust the received time for the message, then try a queue run.
+sudo perl DIR/aux-fixed/setrt 1 -86400
+****
+exim -d-all+retry -q
+****
+no_msglog_check
index 74e375a..3692e95 100644 (file)
@@ -36,7 +36,7 @@ Failed addresses:
 Deferred addresses:
 userx@test.ex
 locking TESTSUITE/spool/db/retry.lockfile
-retry for R:userx@test.ex = *
+retry for R:userx@test.ex = * 0 0
 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
@@ -84,7 +84,7 @@ Deferred addresses:
 userx@test.ex
 locking TESTSUITE/spool/db/retry.lockfile
 deleted retry information for R:test.ex
-retry for R:userx@test.ex = *
+retry for R:userx@test.ex = * 0 0
 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
@@ -133,7 +133,7 @@ Deferred addresses:
 userx@test.ex
 locking TESTSUITE/spool/db/retry.lockfile
 deleted retry information for R:test.ex
-retry for R:userx@test.ex = *
+retry for R:userx@test.ex = * 0 0
 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 04029ae..dd36d02 100644 (file)
@@ -46,12 +46,12 @@ Failed addresses:
 Deferred addresses:
 usery@test.ex
 locking TESTSUITE/spool/db/retry.lockfile
-retry for R:usery@test.ex = *
+retry for R:usery@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 = *
+retry for R:userx@test.ex = * 0 0
 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
@@ -116,13 +116,13 @@ Deferred addresses:
 usery@test.ex
 locking TESTSUITE/spool/db/retry.lockfile
 deleted retry information for R:test.ex
-retry for R:usery@test.ex = *
+retry for R:usery@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 = *
+retry for R:userx@test.ex = * 0 0
 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 38da064..fcb7319 100644 (file)
@@ -143,7 +143,7 @@ opened hints database TESTSUITE/spool/db/retry: flags=O_RDWR
 address match: subject=x@y pattern=*
 y in "*"? yes (matched "*")
 x@y in "*"? yes (matched "*")
-retry for R:x@y = *
+retry for R:x@y = * 0 0
 dbfn_read: key=R:x@y
 on queue longer than maximum retry
 Writing retry data for R:x@y
@@ -153,7 +153,7 @@ dbfn_write: key=R:x@y
 address match: subject=*@V4NET.0.0.0 pattern=*
 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) = *
+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
 Writing retry data for T:V4NET.0.0.0:V4NET.0.0.0:1224
index 3eb97ae..c58e720 100644 (file)
@@ -96,6 +96,7 @@ t1 transport entered
 checking status of 127.0.0.1
 no message retry record
 host retry time not reached: checking ultimate address timeout
+now=tttt received_time=tttt diff=tttt timeout=86400
 127.0.0.1 [127.0.0.1]:1111 status = unusable
 all IP addresses skipped or deferred at least one address
 Leaving t1 transport
diff --git a/test/stderr/0529 b/test/stderr/0529
new file mode 100644 (file)
index 0000000..bed589d
--- /dev/null
@@ -0,0 +1,85 @@
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+admin user
+LOG: MAIN
+  <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+created log directory TESTSUITE/spool/log
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+trusted user
+admin user
+locking TESTSUITE/spool/db/retry.lockfile
+no retry data available
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Considering: x@test.ex
+no domain retry record
+no address retry record
+locking TESTSUITE/spool/db/retry.lockfile
+no retry data available
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Considering: TESTSUITE/test-mail/rmbox
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+After routing:
+  Local deliveries:
+    TESTSUITE/test-mail/rmbox
+  Remote deliveries:
+  Failed addresses:
+  Deferred addresses:
+locking TESTSUITE/spool/db/retry.lockfile
+no retry data available
+added retry item for T:TESTSUITE/test-mail/rmbox:x@test.ex: errno=-22 more_errno=dd flags=0
+LOG: MAIN
+  == TESTSUITE/test-mail/rmbox <x@test.ex> R=r1 T=t1 defer (-22): mailbox is full (MTA-imposed quota exceeded while writing to TESTSUITE/test-mail/rmbox)
+Processing retry items
+Succeeded addresses:
+x@test.ex: no retry items
+Failed addresses:
+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
+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)
+x@test.ex: no retry items
+end of retry processing
+>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+admin user
+LOG: queue_run MAIN
+  Start queue run: pid=pppp
+locking TESTSUITE/spool/db/retry.lockfile
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Considering: x@test.ex
+no domain retry record
+no address retry record
+locking TESTSUITE/spool/db/retry.lockfile
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Considering: TESTSUITE/test-mail/rmbox
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+After routing:
+  Local deliveries:
+    TESTSUITE/test-mail/rmbox
+  Remote deliveries:
+  Failed addresses:
+  Deferred addresses:
+locking TESTSUITE/spool/db/retry.lockfile
+retry record exists: age=ttt (max 1w)
+  time to retry = tttt expired = 0
+retry time not reached for TESTSUITE/test-mail/rmbox: checking ultimate address timeout
+now=tttt received_time=tttt diff=tttt timeout=259200
+LOG: retry_defer MAIN
+  == TESTSUITE/test-mail/rmbox <x@test.ex> R=r1 T=t1 defer (-52): Retry time not yet reached
+Processing retry items
+Succeeded addresses:
+x@test.ex: no retry items
+Failed addresses:
+Deferred addresses:
+TESTSUITE/test-mail/rmbox: no retry items
+x@test.ex: no retry items
+end of retry processing
+LOG: queue_run MAIN
+  End queue run: pid=pppp
+>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
index 993892d..8a8c8ad 100644 (file)
@@ -484,7 +484,7 @@ opened hints database TESTSUITE/spool/db/retry: flags=O_RDWR
 address match: subject=userx@test.ex pattern=*
 test.ex in "*"? yes (matched "*")
 userx@test.ex in "*"? yes (matched "*")
-retry for T:userx@test.ex = *
+retry for T:userx@test.ex = * 0 0
 dbfn_read: key=T:userx@test.ex
 Writing retry data for T:userx@test.ex
   first failed=dddd last try=dddd next try=+86400 expired=0
@@ -600,8 +600,8 @@ EXIM_DBOPEN(TESTSUITE/spool/db/retry)
 returned from EXIM_DBOPEN
 opened hints database TESTSUITE/spool/db/retry: flags=O_RDONLY
 dbfn_read: key=T:userx@test.ex
-retry record exists: age=d (max=604800)
-  time to retry = -ddddd expired = 0
+retry record exists: age=ttt (max 1w)
+  time to retry = tttt expired = 0
 search_tidyup called
 changed uid/gid: local delivery to userx <userx@test.ex> transport=t1
   uid=CALLER_UID gid=CALLER_GID pid=pppp
@@ -650,7 +650,7 @@ opened hints database TESTSUITE/spool/db/retry: flags=O_RDWR
 address match: subject=userx@test.ex pattern=*
 test.ex in "*"? yes (matched "*")
 userx@test.ex in "*"? yes (matched "*")
-retry for T:userx@test.ex = *
+retry for T:userx@test.ex = * 0 0
 dbfn_read: key=T:userx@test.ex
 Writing retry data for T:userx@test.ex
   first failed=dddd last try=dddd next try=+86400 expired=0