cancel
Showing results for 
Search instead for 
Did you mean: 

Make part of an Execution asynchronous

billdoor
Champ in-the-making
Champ in-the-making
Hello, i have the following use case:

I have a Process that is accessed and worked on via webapp.

A process starts wit a user-task, where a user has to input some data, then submit the form. This is followed by 3 short service tasks, followed by another Form, where the user can review the manipulations made by the service tasks.

This has to happen synchronous, meaning the user will click "submit" in the first form and wait for the rpocess to reach the second form for imediate feedback.

When the second task is submitted, it is followed by ~20 service tasks, followed by a closing usertask for final approval.

Here i do NOT want the user to wait for the service-tasks to finish, but for the engine to return control the the main thread and have the application poll the engine for "final tasks". I cannot get activiti to continue along the path that i need to be asynchronous somehow.

the process shortened for better understanding:


<definitions xmlns="http:…">
  <process id="test_process_2" isClosed="false" isExecutable="true" processType="None">
 
 

        <startEvent id="start" name="StartEvent"/>
   
        <userTask activiti:async="false" activiti:exclusive="true" id="input_data" name="enter initial data"></userTask>
   
   <serviceTask activiti:async="false" activiti:class="ShortRunningTasks"
   activiti:exclusive="true" id="feedback_service" name="giving imediate feedback"/>
   
   <userTask activiti:async="false" activiti:exclusive="true" id="feedback" name="giving feedback"></userTask>


        <serviceTask activiti:async="true" activiti:class="LongRunningTasks"
   activiti:exclusive="true" id="longrunning" name="a lot of small tasks that in sum take a relatively long time"/>
   
   <userTask activiti:async="false" activiti:exclusive="true" id="final_approval" name="review and end process"></userTask>
   
   <endEvent id="end" name="EndEvent"/>
   

   <sequenceFlow id="flow1" sourceRef="start" targetRef="input_data"/>
        <sequenceFlow id="flow2" sourceRef="input_data" targetRef="feedback_service"/>
        <sequenceFlow id="flow3" sourceRef="feedback_service" targetRef="feedback"/>
   <sequenceFlow id="flow3" sourceRef="feedback" targetRef="longrunning"/>
   <sequenceFlow id="flow4" sourceRef="longrunning" targetRef="final_approval"/>
   <sequenceFlow id="flow5" sourceRef="final_approval" targetRef="end"/>
  </process>
</definitions>




A Testcase on this somehow "stops" at the longrunning task placeholder.

activiti.cfg.xml

  <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
        <property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
        <property name="jdbcDriver" value="org.h2.Driver" />
        <property name="jdbcUsername" value="sa" />
        <property name="jdbcPassword" value="" />
        <property name="jobExecutorActivate" value="false" />
        <property name="asyncExecutor" ref="asyncExecutor" />
        <property name="asyncExecutorEnabled" value="true" />
        <property name="asyncExecutorActivate" value="false" />
        <property name="defaultFailedJobWaitTime" value="1" />
        <property name="asyncFailedJobWaitTime" value="1" />
    </bean>
    <bean id="asyncExecutor" class="org.activiti.engine.impl.asyncexecutor.DefaultAsyncJobExecutor">
        <property name="defaultAsyncJobAcquireWaitTimeInMillis" value="500" />
        <property name="defaultTimerJobAcquireWaitTimeInMillis" value="500" />
    </bean>


The testcase:

@Rule
    public ActivitiRule activitiRule = new ActivitiRule();

    // also tried activitiRule instead of  ProcessEngines.getDefaultprocessEngine()

    @Test
    @Deployment(resources = {"test_process_2.bpmn"})
    public void test() throws InterruptedException {
        ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("test_process_2");
        Task task = ProcessEngines.getDefaultProcessEngine().getTaskService().createTaskQuery().singleResult();
        ProcessEngines.getDefaultProcessEngine().getFormService().submitTaskFormData(task.getId(), new SimpleInitMap<String, String>("text", "blahblah"));

        Boolean b =true;
        while(b) {
            List<Execution> executions = ProcessEngines.getDefaultProcessEngine().getRuntimeService().createExecutionQuery().processInstanceId(processInstance.getProcessInstanceId()).list();
            b = executions.get(0).getActivityId().equals("longrunning");
            System.out.println(executions.size() + " execution(s) online, waiting…");
            Thread.sleep(1000);
        }
    }



the unittest keeps running in the loop, meaning the only execution is standing on "longrunning". the task consists only of writing 1.000 "a" ta file, after 10 minutes, neither s file is present, nor has the process continued to the final-task.

a "jobquery" gives me one job for the processInstance-id named "async-continuation". But nothing happens.

I have the feeling i am using "async" and "exclusive" wrong somehow. Can someone help please?
1 REPLY 1

warper
Star Contributor
Star Contributor
Hi BillDoor!
According to your config, asyncExecutor is enabled, but not activated.
Set asyncExecutorActivate=true

Also, there is JobTestHelper.waitForJobExecutorToProcessAllJobs that can help waiting for all jobs finished in test.
<code>
package org.activiti.engine.impl.test;

JobTestHelper.waitForJobExecutorToProcessAllJobs(this.processEngineConfiguration, this.managementService, maxMillisToWait, intervalMillis);
</code>