cancel
Showing results for 
Search instead for 
Did you mean: 

A process did not continue from one subprocess to another

mcajvar
Champ in-the-making
Champ in-the-making
I have a process, which consists of 2 subprocesses. When the first subprocess finishes, it should immediately continue to the next subprocess - there are no conditions to prevent that. This has worked as desired for several hundred process instances. However, there is now one process where after reaching the end event of the first subprocess it did not finish and continue to the next subprocess. The process now does nothing. I have checked logs, there were no errors present during execution. The only difference between this and other processes was that I had set logging level to DEBUG for a time, but this should have had nothing to do with the problem.

Is there a way I could "poke" the process to continue? Also, how would I go about figuring out what went wrong? I have a log with all the queries due to the DEBUG setting, if this would help any?
15 REPLIES 15

matej1
Champ in-the-making
Champ in-the-making
Hello again,

it seems this was broken in 5.18.0 (according to our bisecting efforts). I wouldn't call this "unexpected behaviour", because the process enters an invalid state.

I've attached a test and a bpmn file, used with your unit test template for 5.21.0. Note the line with the comment; if it's removed, the test is successful. It works with version 5.17.0 but fails after.

I would be very grateful for advice on how to poke such a stuck process to continue. I don't mind running a few queries and the like, for example to delete the floating rows in ACT_RU_EXECUTION, and adding a hook in our application for RuntimeService.signal().

Thanks!

TestMulti.java:
<code>
package org.activiti;

import java.util.*;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;

import static org.junit.Assert.*;

public class TestMulti {
    private static final String PROCESS_KEY = "test_multi";
    private static final String TASK_KEY = "multi";
    private static final String USER_ID = "testuser";
    private static final String VAR_USERS = "multi_users";

    @Rule
    public ActivitiRule activitiRule = new ActivitiRule();

    @Test
    @Deployment(resources = {"org/activiti/test/test_multi.bpmn"})
    public void test() {
        Map<String, Object> vars = new HashMap<>();
        vars.put(VAR_USERS, Arrays.asList(USER_ID));
        ProcessInstance instance = activitiRule.getRuntimeService().startProcessInstanceByKey(PROCESS_KEY, vars);
        assertNotNull(instance);
        Task task = activitiRule.getTaskService().createTaskQuery().singleResult();
        assertEquals(TASK_KEY, task.getTaskDefinitionKey());
        vars.put(VAR_USERS, new ArrayList<>()); // <– Problem here.
        activitiRule.getTaskService().complete(task.getId(), vars);
        List<ProcessInstance> instances = activitiRule.getRuntimeService().createProcessInstanceQuery().list();
        assertEquals(0, instances.size());
    }
}
</code>

test_multi.bpmn:
<code>
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlnsSmiley Surprisedmgdc="http://www.omg.org/spec/DD/20100524/DC" xmlnsSmiley Surprisedmgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="test_multi" name="Test Multi" isExecutable="true">
    <startEvent id="start" name="Start"></startEvent>
    <endEvent id="end" name="End"></endEvent>
    <userTask id="multi" name="Multi">
      <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="multi_users" activiti:elementVariable="assignee"></multiInstanceLoopCharacteristics>
    </userTask>
    <sequenceFlow id="flow1" sourceRef="start" targetRef="multi"></sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="multi" targetRef="end"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_test_multi">
    <bpmndi:BPMNPlane bpmnElement="test_multi" id="BPMNPlane_test_multi">
      <bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
        <omgdc:Bounds height="35.0" width="35.0" x="120.0" y="260.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">
        <omgdc:Bounds height="35.0" width="35.0" x="550.0" y="260.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="multi" id="BPMNShape_multi">
        <omgdc:Bounds height="55.0" width="105.0" x="300.0" y="250.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="155.0" y="277.0"></omgdi:waypoint>
        <omgdi:waypoint x="300.0" y="277.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="405.0" y="277.0"></omgdi:waypoint>
        <omgdi:waypoint x="550.0" y="277.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>
</code>

matej1
Champ in-the-making
Champ in-the-making
Hello again,

the following diff against 5.21.0 makes my test work, and keeps all other Activiti tests working too (except ShellTaskTest.testOsDetection, as I'm on OpenBSD at home).

The change make sense to me conceptually, but I'm not familiar enough with the codebase to be sure whether this introduces any new issues. I also haven't done tests with our real processes yet.

Thanks,
Matej


diff –git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/behavior/ParallelMultiInstanceBehavior.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/behavior/ParallelMultiInstanceBehavior.java
index d6814c0..b1f7188 100644
— a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/behavior/ParallelMultiInstanceBehavior.java
+++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/behavior/ParallelMultiInstanceBehavior.java
@@ -101,14 +101,15 @@ public class ParallelMultiInstanceBehavior extends MultiInstanceActivityBehavior
   public void leave(ActivityExecution execution) {
     callActivityEndListeners(execution);
    
-    if (resolveNrOfInstances(execution) == 0) {
+    int nrOfInstances = getLoopVariable(execution, NUMBER_OF_INSTANCES);
+
+    if (nrOfInstances == 0) {
      // Empty collection, just leave.
      super.leave(execution);
      return;
     }
-   
+
     int loopCounter = getLoopVariable(execution, getCollectionElementIndexVariable());
-    int nrOfInstances = getLoopVariable(execution, NUMBER_OF_INSTANCES);
     int nrOfCompletedInstances = getLoopVariable(execution, NUMBER_OF_COMPLETED_INSTANCES) + 1;
     int nrOfActiveInstances = getLoopVariable(execution, NUMBER_OF_ACTIVE_INSTANCES) - 1;
    

jbarrez
Star Contributor
Star Contributor
I'm not sure if I understand the fix: what you're doing here is not inspecting the collection, but looking at the loop variable. How would that solve the problem in a generic sense where the collections grows and shrinks?

Furthermore, the parallel multi instance inspects the collection once, and creates instances when the execution arrives in it (as per the BPMN spec). Changing the collection leading to instances being killed sounds to me more like a bug before that got fixed.

matej1
Champ in-the-making
Champ in-the-making
If I understand the spec correctly (section 13.2.7, paragraph 3), the collection should only be evaluated once, but calling resolveNrOfInstances() evaluates the collection again, after it has already been evaluated at creation time.

I created the diff with the assumption that if reevaluating the collection is illegal, its original values should be used. In this case, its original length is nrOfInstances. Changing the collection while activities are executing should not affect anything, as all needed executions should have been created up front.

Anyway, I've also opened an issue on your JIRA as ACT-4212, but I'm not sure where the proper place is for this thread to continue. Your JIRA is really shiny though, we're still stuck on an older, duller version at work. Smiley Happy

Thanks,
Matej

jbarrez
Star Contributor
Star Contributor
Ok, I gave this some thought (and discussed it with Tijs) and I believe you are right. Applied your fix here: https://github.com/Activiti/Activiti/commit/a813e93531a4ca491ef759114d0ef6d5831a6e37

matej1
Champ in-the-making
Champ in-the-making
Thanks! Can't wait enough on 5.22 now. Smiley Happy