Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
TIdSmtpServer not freeing threads
#5
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?  
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,
Reply


Messages In This Thread
TIdSmtpServer not freeing threads - by bluewwol - 10-24-2018, 05:04 PM
RE: TIdSmtpServer not freeing threads - by bluewwol - 10-26-2018, 12:36 AM

Forum Jump:


Users browsing this thread: 1 Guest(s)