So, our fork has a few logging and bayes training mechanisms that run in hook_reset_transaction. They are all very fast, most of the time; but recently one of them broke and started running very slowly. The result: QP would inject an incoming messages into the queue, enter hook_reset_transaction, and 20 minutes later try to respond '250 Queued!'. Of course, by then clients had given up and assumed their messages were not delivered, resulting in duplicate messages and bounces and such.

Here's the patch that I applied to guard against this. On principal, we should do as little as possible between queueing a message and telling the client we queued; if a plugin really needs to something at this juncture, it should probably be using hook_queue_post. Am I right? Or is this going to break something and bite me later :)

I haven't pushed this to my git yet, but I will if nobody points out any fatal flaws or other reasons to change the patch first

-Jared
diff --git a/lib/Qpsmtpd/SMTP.pm b/lib/Qpsmtpd/SMTP.pm
index 258282c..7d75d4e 100644
--- a/lib/Qpsmtpd/SMTP.pm
+++ b/lib/Qpsmtpd/SMTP.pm
@@ -818,10 +818,9 @@ sub queue_pre_respond {
 sub queue_respond {
   my ($self, $rc, $msg, $args) = @_;
   
-  # reset transaction if we queued the mail
-  $self->reset_transaction;
-  
   if ($rc == DONE) {
+    # reset transaction if we queued the mail
+    $self->reset_transaction;
     return 1;
   }
   elsif ($rc == OK) {
@@ -840,6 +839,7 @@ sub queue_respond {
     $msg->[0] ||= 'Queuing declined or disabled; try again later';
     $self->respond(451, @$msg);
   }
+  $self->reset_transaction;
   
   # And finally run any queue_post hooks
   $self->run_hooks("queue_post");

Reply via email to