Manoj Kathiriya
Manoj Kathiriya

Reputation: 3416

How to make retry in Spring TaskExecutor

Following the code which I did for the Async mail sending using Spring 3 TaskExecutor. Code is working fine, I just want to know if any mail failed to sending by any reason then it must be added into queue again and sending must be retried.

I have Googled but did not get information for retry policy.

Help will be highly appreciated !!!

@Service
public class AsyncMailSender implements MailSender {

    /* Logger for Search-Controller Class */
    public static final Logger LOGGER = Logger.getLogger(AsyncMailSender.class);

    @Autowired
    private MailSender mailSender;

    @Autowired
    private TaskExecutor taskExecutor;

    @Autowired
    private VelocityEngine velocityEngine;

    public void send(SimpleMailMessage simpleMessage) throws MailException {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        modelMap.put("user", "Manoj");
        simpleMessage.setText(VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "templates/email.vm", modelMap));
        taskExecutor.execute(new AsyncMailTask(simpleMessage));
    }

    public void send(SimpleMailMessage[] simpleMessages) throws MailException {
        for (SimpleMailMessage message : simpleMessages) {
            send(message);
        }
    }

    private class AsyncMailTask implements Runnable {

        private SimpleMailMessage message;

        private AsyncMailTask(SimpleMailMessage message) {
            this.message = message;
        }

        public void run() {
            LOGGER.info("Sending Emails" + message.getSubject());
            mailSender.send(message);
        }
    }
}

Upvotes: 0

Views: 7380

Answers (3)

JBCP
JBCP

Reputation: 13475

This might not be ideal, but you can use Spring-Retry inside your task like this:

@Service
public class AsyncMailSender implements MailSender {

    @Autowired
    RetryTemplate retryTemplate;

    private class AsyncMailTask implements Runnable {

        private SimpleMailMessage message;

        private AsyncMailTask(SimpleMailMessage message) {
            this.message = message;
        }

        public void run() {
            retryTemplate.execute(new RetryCallback<Void, PersistenceException>() {

                    LOGGER.info("Sending Emails" + message.getSubject());
                    mailSender.send(message);

                    return null;
                }
            });

        }
    }

you can configure the RetryTemplate like this:

@Configuration
public class RetryConfiguration {

    @Bean 
    RetryTemplate retryTemplate() {

        RetryTemplate template = new RetryTemplate();

        TimeoutRetryPolicy policy = new TimeoutRetryPolicy();
        policy.setTimeout(30000L);

        template.setRetryPolicy(policy);

        ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
        template.setBackOffPolicy(backOffPolicy);

        return template;
    }
}

You might also find Spring-Batch useful.

Upvotes: 2

Marcel St&#246;r
Marcel St&#246;r

Reputation: 23525

Spring doesn't do that for you

You have to do the exception handling and queuing yourself. The TaskExecutor itself is inherently retry-capable as it just runs your task at the next configured interval not matter what.

Upvotes: 0

Swapnil
Swapnil

Reputation: 8318

AFAIK, currently there is no way to configure retries with Spring 3 TaskExecutor, there is a SPR associated with that. Having said that, I think Spring retries the method automatically if any exception is thrown. If the exception keeps on recurring, this can be problematic for you (in terms of resource consumption).

Upvotes: 2

Related Questions