cancel
Showing results for 
Search instead for 
Did you mean: 

Change number of retries and interval in job fail retry

heldergr
Champ in-the-making
Champ in-the-making
Hi all,

Im trying to change the default number of retries and the invertal between the retries of a failing job but I could not have success. My attempt is based on the what was suggested in the following links:

- http://forums.activiti.org/content/job-retry-defaults
- https://jira.codehaus.org/browse/ACT-1046

I created customized failed job command factory and command as listed below. Im trying to change the interval using the method setDueDate in the Job, but it always run immediately. 

So I have two doubts.
The first is what is the correct strategy to change the interval between retries? Which method in Job (or another class) should I use?
The second question is how can I change the number of retries to 5, for example? I know I can set the retries in the job, but I should know when the command is executing the first time to set the remaining number of retries. It looks a very basic question, but I could not have an anwser yet.

Process definition:

<blockcode>
   <process id="ProcessoJobRetry" name="Processo Job Retry"
      isExecutable="true">

      <startEvent id="theStart" />
      <sequenceFlow sourceRef='theStart' targetRef='javaService' />

      <serviceTask id="javaService" name="My Java Service Task"
         activiti:class="br.gov.serpro.sigepe.process.application.jobs.retry.JobRetryJavaDelegate"
         activiti:async="true" />
      <sequenceFlow sourceRef='javaService' targetRef='theEnd' />

      <endEvent id="theEnd" />

   </process>
</blockcode>
My job (it only forces a fail):

<blockcode>
public class JobRetryJavaDelegate implements JavaDelegate {

   @Override
   public void execute(DelegateExecution execution) throws Exception {
      throw new NullPointerException();
   }
}
</blockcode>

My failed job command factory:

<blockcode>
public class MyFailedJobCommandFactory extends DefaultFailedJobCommandFactory {

   @Override
   public Command<Object> getCommand(String jobId, Throwable exception) {
      return new MyDecrementJobRetriesCmd(jobId, exception);
   }
   
}
</blockcode>

My failed job command:

<blockcode>
public class MyDecrementJobRetriesCmd implements Command<Object> {

   protected String jobId;
   protected Throwable exception;

   public MyDecrementJobRetriesCmd(String jobId, Throwable exception) {
      this.jobId = jobId;
      this.exception = exception;
   }

   public Object execute(CommandContext commandContext) {

      JobEntity job = Context.getCommandContext().getJobEntityManager()
            .findJobById(jobId);
      
      job.setRetries(job.getRetries() - 1);
      job.setLockOwner(null);
      job.setLockExpirationTime(null);
      job.setDuedate(calculateNextDueDate(10));
      
      if (exception != null) {
         job.setExceptionMessage(exception.getMessage());
         job.setExceptionStacktrace(getExceptionStacktrace());
      }

      JobExecutor jobExecutor = Context.getProcessEngineConfiguration()
            .getJobExecutor();
      
      MessageAddedNotification messageAddedNotification = new MessageAddedNotification(
            jobExecutor);
      TransactionContext transactionContext = commandContext
            .getTransactionContext();
      transactionContext.addTransactionListener(TransactionState.COMMITTED,
            messageAddedNotification);

      return null;
   }

   private Date calculateNextDueDate(Integer secondsDelay) {
      GregorianCalendar gregorianCalendar = new GregorianCalendar();
      gregorianCalendar.add(Calendar.SECOND, secondsDelay);
      return gregorianCalendar.getTime();
   }
   
   private String getExceptionStacktrace() {
      StringWriter stringWriter = new StringWriter();
      exception.printStackTrace(new PrintWriter(stringWriter));
      return stringWriter.toString();
   }
}
</blockcode>

Thanks in advance!

Helder
3 REPLIES 3

jbarrez
Star Contributor
Star Contributor
> The first is what is the correct strategy to change the interval between retries? Which method in Job (or another class) should I use?

The JobExecutor has these properties:

<code>
  protected int maxJobsPerAcquisition = 3;
  protected int waitTimeInMillis = 5 * 1000;
  protected String lockOwner = UUID.randomUUID().toString();
  protected int lockTimeInMillis = 5 * 60 * 1000;
</code>

The  job executor is pluggable, you can inject a subclass of your own. I guess the waitTimeInMillis applies for time between retries.

> The second question is how can I change the number of retries to 5, for example? I know I can set the retries in the job, but I should 
> know when the command is executing the first time to set the remaining number of retries. It looks a very basic question, but I could not
> have an anwser yet.

That's pretty tricky as it is not configurable out of the box. However, there is the SetJobRetriesCmd you could use to fix it quickly.

minhquankq
Champ in-the-making
Champ in-the-making
If we overried JobExecutor and  SetJobRetriesCmd, it will effect for all service tasks of our model, right?
If I want each service task has a different number of retries and interval, can I do it? how if yes?
If I want to retry until task success (don't limit the number of retry), can I do it? how if yes?

Thanks

martin_grofcik
Confirmed Champ
Confirmed Champ
Hi,

If I want each service task has a different number of retries and interval, can I do it? how if yes?
Yes it is feasible. You have to just extend process model and to service task optional extensionElement (there are many examples in the activiti code). After that you have to change JobExecutor behavior to take into account your extensionElement when setting job retries.
If I want to retry until task success (don't limit the number of retry), can I do it? how if yes?
Yes, your custom logic in the job executor has to take care of that.

Regards
Martin