Jump to content
GillesL.

SmtpReady

Recommended Posts

Windows 10, icsv864, Delphi 10.4, VCL app using SMTPClient...

 

I have an app which runs in the background and must send an email (unattended) when a certain event takes place. From time to time the app stops because the component  is not smtpReady:

 

procedure TCustomSmtpClient.CheckReady;
begin
    if not (FState in [smtpReady, smtpInternalReady]) then
      raise SmtpException.Create('SMTP component not ready');
end;
 

Is it possible to have a quiet exception, no need for user to click OK, and have the app recover and continue to work.

 

Anyone has experience with something like this:

 

procedure TCustomSmtpClient.CheckReady;
begin
    while not (FState in [smtpReady, smtpInternalReady]) then

   begin

       Application.ProcessMessages; //not sure if it is warranted
      Sleep(1000); //maybe 100 would be sufficient

   end;
end;
 

Or maybe a better solution...

 

Share this post


Link to post

You don't HAVE TO generate an exception. 

 

Maybe you're talking about what most error loggers are used for.

 

You could also use something like MadExcept that would trap the exceptions and log them for you automatically, send an email, and suppress the exception alerts if you want -- which is useful if you can't modify the source code.

Share this post


Link to post
9 hours ago, GillesL. said:

I have an app which runs in the background and must send an email (unattended) when a certain event takes place. From time to time the app stops because the component  is not smtpReady

The component is not ready because it is still busy with previous request. Maybe an event which triggers email send is right after the previous, before the first email is already sent. Coul be several reasons:

1) the previous email takes long time because the recipient server do not respond fast

2) when sending an email, it don't finishes because of some error

 

You should probably log (ICS has logging facility or you can write log lines to a text file, easy) all events and steps that occurs in your application and see if it is correct.

 

Waiting for readiness in a wait loop is not the best idea. It is much better to use events.

 

The event which triggers the email sending should push that info into a queue, check if the smtp component is done with previous email and fetch the next email from the queue. If not ready, just do nothing. When the component event tells it has finished sending an email, it checks the queue for the next mail to be sent and do it if there is one or just do nothing. Using vent everywhere is the key to success!

 

Share this post


Link to post

Change to using the TIcsMailQueue component, you prepare email using THtmlSmptCli after which you forget about it while a thread tries to send the mail using several mail servers over several days, all queued.  Designed specifically for servers to call for help, Used in the OverbyteIcsSslMultiWebServ.dpr sample. 

 

Angus

 

Share this post


Link to post

Thanks. I did not realize that the property "State"  was published, which makes it easier so I do not have to modify the source.

Share this post


Link to post
11 hours ago, Angus Robertson said:

Change to using the TIcsMailQueue component, you prepare email using THtmlSmptCli after which you forget about it while a thread tries to send the mail using several mail servers over several days, all queued.

That's actually quite impressive, I didn't know ICS has these functions built-in! Simple question - does it (or offers a way to) handle backlogs? What happens if an E-mail could not be sent because no connection could be made and the application shuts down?

Share this post


Link to post

I'd have a list of unprocessed requests that feed the sending agent. If the agent dies, the list sticks around.

 

The challenging part is the potentially diverse time dynamics involved.

 

You could use a multi-threaded design to feed hundreds of messages per minute to an API for a commercial SMTP service, like SendGrid, or just use a simple loop that sleeps for sending to a shared hosting account that limits you to 100 per hour or 500 per day. If you try sending through your ISP, like your cable company, you risk getting shut down if you exceed certain limits that they don't like to disclose.

 

Sending stuff through an SMTP relay is, on the surface, one of the simplest things you can do. But the practical implications of it -- being that it's probably the single most widely abused resource in the entire internet world -- are that your sending agent needs to be highly resilient and pay close attention to the error codes it's getting. It needs to be programmed like that song about The Gambler -- know when to hold 'em, know when to fold 'em, know when to walk away, know when to run... You do not want your SMTP host to shut you down, especially when it's your ISP or web host b/c they could just as easily shut down your entire frigging account! 

 

That's a really big benefit of using a 3rd-party SMTP host -- the worst they'll do is shut of your SMTP account. And it's easy to find another one. (Better yet, set up several before you even get started.)

Share this post


Link to post
Quote

Change to using the TIcsMailQueue component, you prepare email using THtmlSmptCli after which you forget about it while a thread tries to send the mail using several mail servers over several days, all queued.

 

That's actually quite impressive, I didn't know ICS has these functions built-in! Simple question - does it (or offers a way to) handle backlogs? What happens if an E-mail could not be sent because no connection could be made and the application shuts down?

I wrote the Mail Queue component 10 years ago and it was available from the Magenta Systems site, only integrated with ICS early last year. 

 

For persistence, all emails are written as disk files and into database (simple text file).  You specify how many attempts to send each email with what gap, which are repeated for each server (if more than one) or it will look-up MX records and send directly, but that really only works if the server has proper reverse DNS for major email providers.  

 

Once sent, the file is deleted or moved to an archive directory.  The sample app has a window to view the queue in a grid to see what is left in the queue and delete stuff. and I include that window in my applications.  So really all the concepts of a forwarding SMTP mail server, but it would need a better database design for heavier traffic, it really intended to send hundreds of emails at a time, not thousands.

 

Angus

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×