[Mailman-Developers] Re: [Mailman-Users] Bounce Options

Bob Puff@@NLE bob@nleaudio.com
Sat, 01 Dec 2001 19:56:55 -0500


Ok, I've thought more about this today, and optimized my code a little.. <g>

Check this out:

min_bounce_days = 5 (max # of days we say it will take for a bounce to come to us)
max_bounce_days = 14 (number of days to allow bouncing)

Once every day (really doesn't matter when), post_counter is incremented ONLY if a message went out that day.  This would probably be a 16 bit non-signed number.

There are only three numeric entries (16 bit unsigned as well) needed per user.  They are: first_bounce, last_bounce, and bounce_count.

Here's the logic:

Upon receiving a bounce, the user record is called up.  

if user(first_bounce) = null  {  user(first_bounce)=post_counter
                                 user(bounce_count)=0 }
user(last_bounce)=post_counter;
user(bounce_count)++;
print to the log "User x Bounced "user(bounce_count)" times."
   
Now for the script that gets run once a day:

if there were any posts today, do this: post_counter++;
for all users:
if user(first_bounce) <> NULL {
  if (post_counter - user(first_bounce)) < min_bounce_days then break out, exit.
  # We don't want to do anything for the first few days.. just keep logging, and exit.
  if (post_counter - user(last_bounce)) > min_bounce_days {
          user(first_bounce) = user(last_bounce) = NULL;
          print to log, "User x stopped bouncing." } - exit out.
  # our last bounce was a while ago, so looks like we've been delivering 
  # mail ok, so we reset the counters and exit.
  if (user(last_bounce) - user(first_bounce) > max_bounce_days {
          remove the sucker!  or set him to "bouncing nomail"
          also don't forget to set user(first_bounce) = NULL  }
 }

Pretty simple code, huh?  One thing that needs fixing is the wrapping of the 16 bit numbers, and taking care of the proper subtraction when one number wraps.

The way it works is this:
When a user fresh bounces, it sets their first_bounce and last_bounce to the current post_counter.  Now let's say the user stops bouncing mail.  After a while, we'll see that our last_bounce number is getting further from the current post_counter.  So if we see that last_bounce gets more than say 5 counts (days) away from current, we can safely assume they haven't been bouncing, and can clear their entries.

If a user is still bouncing, we'll see the last_bounce stay pretty close to post_counter.  So now we have to see how long they have been bouncing, which can be done by simply subtracting last_bounce from first_bounce.  The code in the preceeding paragraph cleans up any old junk, so we can be certain this is current data.  

The beauty of this is that even on a list that gets a post every other week, this code will work.  Or if you get 100 messages/day, it still works, because it's based on message days.  Those who have inactive lists may want to set max_bounce_days to something like 7-8, and will have to realize that this means 7-8 days messages went out.. so if you have 1 message per week, it would take 7-8 weeks for the first user to be flagged.  

The other variable, min_bounce_days, lets you tune it for however long you think it would take a mail server to respond with a bounce.  I've seen 5 day messages, so that might be a good initial value.  The code will wait for that many "message days" before considering a one-time bouncer has stopped bouncing... which is no big deal, because we haven't done anything drastic at this point anyway.  

What do you guys think?

The above code is not in any defined programming language.. :-)

Chuq: I do like the idea of the warning messages.  Could probably scan for that "bounce-nomail" flag in the same once-a-day script and generate emails at specified days as you said.

Bob