views:

337

answers:

3

Hi everyone,

I would like to implement asynchronous email sending in my web application when users register for a new account. This is so that if there is a problem or delay in sending the email message (e.g. the mail server is down or the network connection to the mail server is slow) the user won't be kept waiting for the sending to complete.

My web app is built using Spring and Hibernate's implementation of JPA.

What would be the best and most reliable way for me to implement asynchronous email processing in this web application?

I am thinking about persisting the email information in a database table which is then regularly polled by a Quartz (http://www.opensymphony.com/quartz/) scheduled job for updates and when it finds new unsent emails, it attempts to send them.

Is this a reasonable way of implementing what I want?

Thanks.

Edit:

The most voted on response is to leave the sending of mail as a synchronous call but what's triggered my thinking that an asynchronous approach might be best is that I'm currently using GMail as my outbound mail server (this is for testing while developing) and I'm experiencing a 25 second delay in response from when my app tries to send the email to when the call to the mail send function returns. What do you think?

+1  A: 

You can implement queueing by hand, using MySQL or some other persistent mechanism, but you could also use JMS for queueing. It's pretty much a perfect match for just this kind of situations.

In that case I would be tempted by splitting the mail component off from the main app, and let the two communicate using JMS. The main app puts a message in the JMS and the mailer app would subscribe to the queue and try to process the messages.

JMS can be made persistent (to e.g. MySQL) pretty easily by configuration.

The advantage of spliting the webapp is that you abstract away the notification mechanism and could in the future implement e.g. Google Wave or IRC or whatever without having to touch your main app.

Someone else suggested to use a postfix or sendmail and let them handle the queueing. That is also a great solution, especially if you put the postfix or sendmail on localhost and let it route the messages further. Do try to configure that mailer program such that only mail from localhost is allowed to be routed, to prevent creating an open mailer :)

EDIT clarified the use of JMS + comment on local mailer daemon

extraneon
JMS does not equal Java Mail. JMS has nothing to do with e-mail.
Chris Kaminski
@Chris No, the queueing can be implemented by JMS.
extraneon
@extraneon: it could, but I think it's overly complex for what the user wants to do. Certainly doable, and in some architectures, maybe preferable (an ESB, for instance, HIPAA compliance, perhaps).
Chris Kaminski
A: 

It is fairly reasonable, this is the kind of thing Quartz was build for.

However, note that you don't need to schedule through the database at all (unless the server downtime is a real issue). You can simply schedule a Quartz job without database access (the simplest Quartz examples show you how).

Otherwise, if you do choose the database access you have the possibility of sending the emails from another application entirely (a nice thing if you need it).

laura
+3  A: 

I would suggest that you don't bother. Most Unix-style MTAs invented and perfected deferred sending decades ago, and you shouldn't be reinventing the wheel. You'll do it poorly (in comparison to sendmail or postfix), and you'll miss something. My best advice is to use the Java Mail APIS javax.mail and let the MTA deal with the asynchronous part.

Chris Kaminski
The problem with this approach is that I'm currently using gmail as my outbound mail server (this is for testing) and I'm experiencing a 25 second delay in response from when my app tries to send the email to when the call to the mail send function returns. This is what's triggered my thinking that an asynchronous approach might be best. What do you think?
Annie
@Denise I would agree with the asynchronous bit. You could run a background thread in your Servlet Engine, that takes JavaMail "Messages" out of a list or vector and does the processing.
Chris Kaminski