10-26-2018, 12:36 AM
Remy;
I do still have some threads not being freed, but will focus some attention on those in the next few days.
Threads associated with VAction := mReject from OnMailFrom event and VAction := rInvalid from OnRcptTo event and threads where the client disconnected are currently freed after five minutes. There are a few threads the remain active well beyond this that I have not yet determined a cause. I had also assumed that the TerminateWaitTime would impact the time interval for these to be cleaned up, however it seems TerminateWaitTime has no impact on this.
In the mean time I have adjusted the OnMailFrom event to include a ASender.Connection.Disconnect which swams to be making a big improvement, however is this a foolish solution?
I have also added a procedure on a 30 minute timer that cleans up other threads (a heavy handed remedy of the symptom)
While maybe technically inept my app now frees threads immediately after a message is received, after the sender is determent bad, and after a recipient is determined to be bad.
After five minutes the threads Indy believes to be complete are cleaned up.
After thirty minutes I brute force clean up the remaining threads.
Thanks again for the help,
I do still have some threads not being freed, but will focus some attention on those in the next few days.
Threads associated with VAction := mReject from OnMailFrom event and VAction := rInvalid from OnRcptTo event and threads where the client disconnected are currently freed after five minutes. There are a few threads the remain active well beyond this that I have not yet determined a cause. I had also assumed that the TerminateWaitTime would impact the time interval for these to be cleaned up, however it seems TerminateWaitTime has no impact on this.
In the mean time I have adjusted the OnMailFrom event to include a ASender.Connection.Disconnect which swams to be making a big improvement, however is this a foolish solution?
Code:
procedure TdSmtpServ.WwolSmtpServMailFrom(ASender: TIdSMTPServerContext; const AAddress: string; AParams: TStrings; var VAction: TIdMailFromReply);
var
s1 : string;
begin
if Trim(AAddress) = '' then
begin
VAction := mReject;
s1 := 'mReject';
TmySmtpItem(ASender.Data).LastEvent := 'MailFrom mReject';
ASender.Connection.Disconnect;
end
else
begin
VAction := mAccept;
s1 := 'mAccept';
TmySmtpItem(ASender.Data).LastEvent := 'MailFrom mAccept';
end;
end;
I have also added a procedure on a 30 minute timer that cleans up other threads (a heavy handed remedy of the symptom)
Code:
procedure TdSmtpServ.TerminateThreads;
var
i : Integer;
LContext : TIdContext;
LList : TIdContextList;
TermTime : TDateTime;
begin
// try terminate extra threads...
TermTime := Now - (1 / 48); // half an hour ago
if WwolSmtpServ.Contexts <> nil then
begin
LList := WwolSmtpServ.Contexts.LockList;
try
// for i := 0 to LList.Count - 10 do
for i := LList.Count - 1 downto 0 do
begin
LContext := TIdContext(LList.Items[i]);
Assert(LContext <> nil);
Assert(LContext.Connection <> nil);
if (TmySmtpItem(LContext.Data).Start < TermTime) then
LContext.Connection.Disconnect;
end;
finally
WwolSmtpServ.Contexts.UnLockList;
end;
end;
end;
While maybe technically inept my app now frees threads immediately after a message is received, after the sender is determent bad, and after a recipient is determined to be bad.
After five minutes the threads Indy believes to be complete are cleaned up.
After thirty minutes I brute force clean up the remaining threads.
Thanks again for the help,