Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
TIdSmtpServer not freeing threads
#6
(10-26-2018, 12:36 AM)bluewwol Wrote: I do still have some threads not being freed

And what are those threads actually doing?  And do you get an OnDisconnect event fired for them?

(10-26-2018, 12:36 AM)bluewwol Wrote: 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.

If a client disconnects, its thread should be stopping itself immediately.  If it is not, then there is a serious problem with your server.

(10-26-2018, 12:36 AM)bluewwol Wrote: 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.

No, it does not.  In fact, it has NO EFFECT WHATSOEVER in Indy 10 at all.  It is a legacy property that is NO LONGER IMPLEMENTED.

However, even in Indy 9 and earlier, where it USED to be implemented, it had NO EFFECT on running client threads during normal server usage.  The property applied ONLY when the server was being deactivated.  The property specifies the total amount of time the server waits for all active threads to terminate.  In Indy 8, if a timeout occurred, the deactivation would simply exit immediately.  In Indy 9, the deactivation would raise an EIdTerminateThreadTimeout exception instead.  In Indy 10, the property is ignored altogether, deactivation waits as long as it takes for all threads to terminate.

(10-26-2018, 12:36 AM)bluewwol Wrote: 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?

Yes, it is foolish, not to mention a violation of the SMTP protocol.  Just because a client sends a MAIL FROM command with a blank address should not doom that client to an immediate disconnection.  In fact, MAIL FROM:<> is a valid command (see RFC 5321 Section 3.6.3 regarding "undeliverable mail" notifications).

Now, if a client sends multiple commands that repeatedly fail, that would be a different case to consider.

You might also consider using the TIdSMTPServer.OnSPFCheck event to make sure clients are coming from IPs that are even authorized to access your server in the first place.

(10-26-2018, 12:36 AM)bluewwol Wrote: I have also added a procedure on a 30 minute timer that cleans up other threads (a heavy handed remedy of the symptom)

Very heavy handed.  I would opt for a different solution that does not rely on a looping timer, or even accessing the server's Contexts list.

First, start with assigning a non-infinite ReadTimeout for each connected client, such as in the OnConnect event.  If a client connects and then doesn't send a command for awhile, an exception will be raised that will close the connection.  You might also go as far as using AContext.Connection.Socket.SetSockOpt() to set a non-infinite SO_SNDTIMEO writing timeout, too (Indy currently does not have any kind of WriteTimeout property), to handle cases where a client connects and does not read anything the server sends, causing a thread blockage if the client's inbound buffer fills up.

Beyond that, TIdSMTPServer is derived from TIdCmdTCPServer, which has virtual DoExecute() and ReadCommandLine() methods.  I would override one of those to handle the TmySmtpItem.StartStart check.  And I would not use a TDateTime for that check, since Now() is sensitive to local clock changes.  I would use Indy's Ticks64() and ElapsedTicks() functions instead, which do not care about the clock at all.

Reply


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

Forum Jump:


Users browsing this thread: 2 Guest(s)