cancel
Showing results for 
Search instead for 
Did you mean: 

Regression. Timer variable not resolved 5.8 -> 5.9

mikfreeman
Champ in-the-making
Champ in-the-making
Hi,
   Huge Activiti fan but I'm stumped by this one. I'm using a "ProcessConfig" class to look up various properties.
However following an upgrade from 5.8 to 5.9 the below configuration no longer works.
The timeDuration property in the Timer event is not resolved and as a result the Timer is effectively ignored.

<intermediateCatchEvent id="timerintermediatecatchevent3" name="Wait for Collection">
  <timerEventDefinition>
    <timeDuration>PT${processConfig.getDuration('timeBetweenTasks')}S</timeDuration>
  </timerEventDefinition>
</intermediateCatchEvent>

Setting the "timeBetweenTasks" directly as a variable without using the "processConfig" class works.

<intermediateCatchEvent id="timerintermediatecatchevent3" name="Wait for Collection">
  <timerEventDefinition>
    <timeDuration>PT${timeBetweenTasks}S</timeDuration>
  </timerEventDefinition>
</intermediateCatchEvent>

Any ideas on how to resolve this?

Thanks

Michael
6 REPLIES 6

trademak
Star Contributor
Star Contributor
Hi Michael,

Would it be possible to create a test case for this, so I can run it myself?
Maybe create a JIRA and attach the test case.

Thanks,

mikfreeman
Champ in-the-making
Champ in-the-making
Hi,
   I have been trying to recreate. But I can't get a simple unit test to make it past the timer. I have attached an example that uses the PluggableActivitiTestCase.

Not sure what I'm doing wrong here.

If you take the timer out the test passes

trademak
Star Contributor
Star Contributor
Hi,

I tried to reproduce it, but it's working fine for me.
I attached my test case.

Best regards,

mikfreeman
Champ in-the-making
Champ in-the-making
Hi,
   Thanks for taking the time to respond and for your patience. Could you help me understand why the second version of the test fails?

This version passes.
public class TimerIssueTest extends PluggableActivitiTestCase {

  @Deployment(resources="TimerIssueTest.testTimerIssue.bpmn20.xml")
  public void testTimerIssue() {
    Map<String, Object> variables = new HashMap<String, Object>();
    variables.put("test", "2");
    ProcessInstance processInstance = runtimeService
        .startProcessInstanceByKey("TimerIssueTest", variables);

    Task task = taskService.createTaskQuery().taskName("Complete Order")
        .singleResult();
    assertEquals("Complete Order", task.getName());

    taskService.complete(task.getId());
   
    JobQuery jobQuery = managementService.createJobQuery().processInstanceId(processInstance.getId());
    assertEquals(1, jobQuery.count());
    Calendar nowCal = new GregorianCalendar();
    nowCal.add(Calendar.MINUTE, 1);
    ClockUtil.setCurrentTime(nowCal.getTime());
    waitForJobExecutorToProcessAllJobs(10000L, 1000L);
    Task task2 = taskService.createTaskQuery().taskName("Send Order").singleResult();
    assertNotNull(task2);
    assertEquals("Send Order", task2.getName());

    taskService.complete(task2.getId());

  }
 
}

I would expect this test to wait for 60 seconds before completing. However it immediately fails on the assertNotNull for task2

public class TimerIssueTest extends PluggableActivitiTestCase {

  @Deployment(resources="TimerIssueTest.testTimerIssue.bpmn20.xml")
  public void testTimerIssue() {
  
    Calendar nowCal = new GregorianCalendar();  //Using the current time
    ClockUtil.setCurrentTime(nowCal.getTime());
  
    Map<String, Object> variables = new HashMap<String, Object>();
    variables.put("test", "60");//Wait for 60 seconds
    ProcessInstance processInstance = runtimeService
        .startProcessInstanceByKey("TimerIssueTest", variables);

    Task task = taskService.createTaskQuery().taskName("Complete Order")
        .singleResult();
    assertEquals("Complete Order", task.getName());

    taskService.complete(task.getId());
   
    JobQuery jobQuery = managementService.createJobQuery().processInstanceId(processInstance.getId());
    assertEquals(1, jobQuery.count());
//    Calendar nowCal = new GregorianCalendar();
//    nowCal.add(Calendar.MINUTE, 1);
//    ClockUtil.setCurrentTime(nowCal.getTime());
    waitForJobExecutorToProcessAllJobs(70000L, 1000L); //Wait for 70 seconds
    Task task2 = taskService.createTaskQuery().taskName("Send Order").singleResult();
    assertNotNull(task2);
    assertEquals("Send Order", task2.getName());

    taskService.complete(task2.getId());

  }
 
}

trademak
Star Contributor
Star Contributor
Hi,

The idea of this unit test is to set the ClockTime after the time the timer job needs to fire.
Then the waitForJobExecutorToProcessAllJobs will execute these jobs.
If you don't include the time addition, you'll run into an endless Thread sleep.

Best regards,

mikfreeman
Champ in-the-making
Champ in-the-making
Hi Tijs,
         Thanks again. The issue we are having seems to happen for timers with a wait time below 5 seconds. With a wait time of 5 seconds or above the timers wait (We have 4 timers in total, generally after a script task).

If the time is less than 5 seconds it seems to ignore them (We had the time set to PT3S)

The following code in the JobManager class seems to confirm this. The waitTimeInMillis is 5 seconds (Confirmed when debugging)

    // Check if this timer fires before the next time the job executor will check for new timers to fire.
    // This is highly unlikely because normally waitTimeInMillis is 5000 (5 seconds)
    // and timers are usually set further in the future
   
    JobExecutor jobExecutor = Context.getProcessEngineConfiguration().getJobExecutor();
    int waitTimeInMillis = jobExecutor.getWaitTimeInMillis();
    if (duedate.getTime() < (ClockUtil.getCurrentTime().getTime()+waitTimeInMillis)) {
      hintJobExecutor(timer);
    }

No idea why this does not cause the same issue in 5.8.

Should I raise a defect?

Thanks again

Michael