[exim-dev] Change delay ACL modifer precision to millisecond…

Top Page
Delete this message
Reply to this message
Author: Paul Fisher
Date:  
To: exim-dev
Subject: [exim-dev] Change delay ACL modifer precision to milliseconds
The new ratelimit ACL condition is much more interesting when delay
can be used with time values that are more precise than a second. A
very small patch to switch the delay ACL over to using milliseconds is
attached.

This change permits the ratelimit ACL condition to be used in much the
same way as the smtp_ratelimit_* variables, which permit delays of
less than a second.

We're interested in throttling senders down to a particular message
rate, and to do so in a useful manner, we require more precise delay
times.

Our current rule is along the lines of:

  warn
    ratelimit  = 12 / 10s / strict
    delay      = ${eval: $sender_rate - $sender_rate_limit}s


While only precise to a single decimal place, this results in Exim
throttling senders down to a rate of approximately 1.2 messages per
second (after a short initial burst).

eval only deals with integers, and since $sender_rate is not an
integer, the actual eval for our delay is:

${eval:
${extract{1}{$sender_rate}}-$sender_rate_limit}.${extract{2}{.}{$sender_rate}}s

This works fine, but it's rather ugly. Various places in Exim seem to
only want to work on integers, while other places in Exim expect
floats. One possible modification would be to add a new sub-second
integer time unit (ie. milliseconds or microseconds), and then
represent $sender_rate as an integer. Another option would be to add
an eval-like expansion that can process floats.

This patch uses millisleep, and one annoyance of using millisleep is
that it depends on milliwait -- which will prevent exiwhat from
returning information about a process while it's sleeping. This
however, is no worse than exiwhat's behavior with smtp_ratelimit_*
(which also uses millisleep). Perhaps nanosleep should be used instead
on platforms that support the call.
diff -r -u exim-4.60/src/acl.c exim-4.60-new/src/acl.c
--- exim-4.60/src/acl.c    2005-11-28 02:57:32.000000000 -0800
+++ exim-4.60-new/src/acl.c    2005-12-01 17:28:57.000000000 -0800
@@ -2530,7 +2530,7 @@


     case ACLC_DELAY:
       {
-      int delay = readconf_readtime(arg, 0, FALSE);
+      int delay = readconf_readtime(arg, 0, TRUE);
       if (delay < 0)
         {
         *log_msgptr = string_sprintf("syntax error in argument for \"delay\" "
@@ -2539,8 +2539,8 @@
         }
       else
         {
-        HDEBUG(D_acl) debug_printf("delay modifier requests %d-second delay\n",
-          delay);
+        HDEBUG(D_acl) debug_printf("delay modifier requests %.3g-second delay\n",
+          delay/1000.0);
         if (host_checking)
           {
           HDEBUG(D_acl)
@@ -2564,7 +2564,7 @@


         else
           {
-          while (delay > 0) delay = sleep(delay);
+          if (delay > 0) millisleep(delay);
           }
         }
       }