cancel
Showing results for 
Search instead for 
Did you mean: 

How to retry failed emails ?

Former Member
0 Kudos

I am using hybris 5.1.0 and accelerator.When there is a email is sent as part of user registration, order creation, etc , if the email sending fails, I want to retry email sending (few times ,for next 2hr- which should be configurable in local.properties) .

I can see accelerator uses *process.xml for most of the work flows
e.g For customer registration , accelerator uses the customerRegistrationEmailProcess.xml , which uses SendEmailAction to send emails.

Any idea how this retry can be implemented with its attributes such as retry count, how long to retry -are dynamic for each flow ?

Accepted Solutions (1)

Accepted Solutions (1)

Former Member

I solved myself, For the benefit of many, the steps involved are described below.

1) Where ever the email sending is done using getEmailService().send() , RetryLaterException has to be thrown in case of failure

e.g SendEmailAction.java ->Extend this class and create a new class and override

 @Override
 public void executeAction(final de.hybris.platform.processengine.model.BusinessProcessModel businessProcessModel)
         throws RetryLaterException
 {
     for (final EmailMessageModel email : businessProcessModel.getEmails())
     {
         getCustomerServiceEmails(email);
         getEmailService().send(email);
         if (!email.isSent())
         {
             int emailRetryDelay =5 ;//in minutes , //TODO read it from local.properties
             LOG.info("Email sending failed - for " + businessProcessModel + " and its code " + businessProcessModel.getCode());
             final RetryLaterException retryLaterException = new RetryLaterException();
             retryLaterException.setDelay(1000L * 60L * emailRetryDelay); // in milliseconds
             retryLaterException.setMethod(Method.LINEAR);
             throw retryLaterException;
         }
     }
 } 


2) DefaultTaskExecutionStrategy is not handling the retry fully with predictable delay etc. So Extend DefaultTaskExecutionStrategy and create a new class and over ride handleRetry() as below

 @Override
 public Date handleRetry(final TaskService taskService, final TaskRunner<TaskModel> runner, final TaskModel model,
         final RetryLaterException retry, final int currentRetries)
 {
     final int emailRetryCount = 5;// TODO read it from local.properties
     log.info("Before evaluating retrying of  Process " + ((ProcessTaskModel) model).getProcess() + " and action "
             + ((ProcessTaskModel) model).getAction());
     Date next = null;
     if (model instanceof ProcessTaskModel
             && (((ProcessTaskModel) model).getAction().equalsIgnoreCase("sendEmails"))) //TODO match whatever actions which sends email 
     {
         if (model.getRetry() < emailRetryCount - 1)
         {
             next = retry.getMethod().nextInvocation(new Date(), currentRetries, retry.getDelay());
             log.info("Before retrying of`process " + ((ProcessTaskModel) model).getProcess() + " with action "
                     + ((ProcessTaskModel) model).getAction() + " next at: " + next + " retry count:" + (model.getRetry() + 1));
         }

     }
     return next;
 }

3). Register the above two classes in the *spring.xml and deploy.

4). To simulate the testing , go to HAC->platform->config. Search for smtp. change the ip address to a invalid one. Now try Forgot pwd functionality (or any flow which send emails)

5). Watch the server console, you should see the retries every minute for 5 (first+4 retries) times.

Former Member
0 Kudos

Hi Sriram can you please help me to understand how SendEmailAction's executeAction() and DefaultTaskExecutionStrategy's handleRetry() are linked. how there relationship is established.

shaktimohanty
Explorer
0 Kudos

Hi Sriram,

I am also a little confused about the relationship between sendEmailAction and DefaultTaskExecutionStrategy. Could you explain how is the relationship defined.

Answers (3)

Answers (3)

Former Member
0 Kudos

You can look into the workflow retry policy, assuming you want to retry failed jobs;

https://wiki.hybris.com/display/release5/Workflow+Retry+Policy

However I don't think that would work ideally in a cluster env.

Former Member
0 Kudos

Just to add you could go with a quick custom service if you can't use the task service; define retry status and counter attributes in the model, flag the failed events, build a search query dao of failed events, and publish/send them again until count of retry < retry_size_limit (and increment counter of course).

Former Member
0 Kudos

I would suggest to use the task engine for this, have a look at the technical guide:

https://wiki.hybris.com/display/release5/task+-+Technical+Guide

Example:

 @Override
 public void run(final TaskService paramTaskService, final TaskModel task) throws RetryLaterException {
     if (!getEmailService().send((EmailMessageModel) task.getContext())) {
         if (task.getRetry().intValue() <= 10) {
             LOG.warn("email not sent successfully, trying to re-send email");
             final RetryLaterException e = new RetryLaterException("unable to send email");
             e.setDelay(60 * 60 * 1000);
             throw e;
         }
         else {
             throw new IllegalStateException("unable to send email after " + task.getRetry() + " retries");
         }
     }
     else {
         LOG.info("email sent successfully");
     }
 }
Former Member
0 Kudos

Yes , I too looked at this. But I am not sure how the above code be used in process XML s action nodes such as sendmailaction? Any idea?

Former Member
0 Kudos

if (!getEmailService().send(email)) { throw new RetryLaterException(); }

Well this would retry. You don't control the count, how long to try etc. It exponentially waits longer each try. This is bad.

I would avoid this approach. Make a CronJob and run it regularly to "clean up" failures.
Former Member
0 Kudos

Even I tried throwing RetryLaterException and found that it is not predictive in waiting . Is there any way task service and process XML action nodes be used together to meet my needs?