Balaji Vignesh
Balaji Vignesh

Reputation: 456

What is the best approach for sending emails in java with out blocking main code flow?

My server requires sending emails pretty frequently. The emails are heavy; they have attachments as well as inline images in them.

My present code blocks code until an email is sent. (loosing 5 to 6 seconds for every email)

What is the best approach for handling the emails with out blocking the main code flow?

If you are suggesting threads, please elaborate on how efficiently it could be handled?

Upvotes: 0

Views: 3892

Answers (2)

CuriousMind
CuriousMind

Reputation: 3173

There are multiple ways to achieve this functionality.

Synchronous Call

This is the one which you are already using. Code (synchronously) invokes Java Mail API and waits for API to complete the execution. The process may take time depending on the complexity of building the email message (fetching records from Database, reading images/documents (attachments), communication with Mail Server etc.

Trade-offs

  1. For individual requests(web/desktop), response latency will increase based on the time it takes to construct and send email.
  2. An exception in sending email, may require redo of entire process (if retried).
  3. Transactional data (e.g. DB) may be rolled back, due to exception while sending email. This may not be desired behavior.
  4. Overall application latency will increase, if similar functionality is invoked by multiple users concurrently.
  5. Email retry functionality may not be possible, if email sending code is tightly coupled with other functional code.

Multithreading Approach

Create a separate thread to asynchronously send an email. Calling code need not have to wait for Email send functionality to complete and execute rest of the code. Ideally, should make use of ThreadPool, instead of blandly creating new threads.

Trade-offs

  1. Though, request latency will go down, it is still not reliable. Any exception occurred while constructing/sending email may result into, no email sent to user.

  2. Email sending functionality can't be distributed across multiple machines.

  3. Retry functionality is possible, since email code is separated into separate class. This class can be independently called, without a need of redoing other things.

Asynchronous Processing

Create a class, which accepts Email request and stores it in either database or messaging infrastructure (e.g. JMS). The message listeners will process the task as and when it arrives and update the status against each task.

Trade-offs

  1. Email requests can be processed in distributed mode.
  2. Retry email possible, without having any side effects.
  3. Complex implementation as multiple components are involved in processing, persisting email requests.

Upvotes: 2

Jay
Jay

Reputation: 1119

You can efficiently do this if you spawn a thread for every email you have to send.

One way to do it is as follows:


You would need a class that is just a pure extension of Thread:

public class MailSenderThread extends Thread {        
    @Override
    public void run() {
        try {
            // Code to send email
        } catch (Exception ex) {
            ex.printStackTrace();
        }    
    }    
}

And when you want to send email, you can do:

new MailSenderThread().start();

That is the shortest/easiest way I could think of.


You can refer to an example in my public repository as well. It's off-topic but it gets the concept.

Upvotes: 0

Related Questions