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");