cancel
Showing results for 
Search instead for 
Did you mean: 

Regarding multi instance behaviour

vram
Champ in-the-making
Champ in-the-making
Hello,

I am trying to run a multi instance sequential behaviour for my service task. I have set the loop counter to 5.

My listener receives a start event from  activiti for each iteration i.e, in this case it receives 5 start events.

But , I get only one end event . Does this single end event mark the completion of all the iterations ?

Also, in the case of failure in any one of the iteration ,  how will this end happen?

It would be great if someone could clarify on this.


Thanks
5 REPLIES 5

frederikherema1
Star Contributor
Star Contributor
An error in a multi-instance is handled the same way as it would occur in a simple service-task: transaction is rolled back and process is back in the state it first was.

I assume you're referring to an "execution-listener" on the multi-instance serviceTask? AFAIK, there are called for every execution of the loop:

Take for example org.activiti.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior

/**
   * Called when the wrapped {@link ActivityBehavior} calls the
   * {@link AbstractBpmnActivityBehavior#leave(ActivityExecution)} method.
   * Handles the completion of one instance, and executes the logic for the sequential behavior.   
   */
  public void leave(ActivityExecution execution) {
    callActivityEndListeners(execution);

If you are indeed referring to a execution-listener on the service-task, and you only see the end-execution-listeners executed once, please comment and perhaps include the bpmn20.xml file.

vram
Champ in-the-making
Champ in-the-making
I am referring to the execution listener and the end execution listener is executed only once ( after the completion of all the iterations).I have attached my xml herewith

<?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: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="Dia1" name="dia1">
    <documentation>Place documentation for the 'dia1' process here.</documentation>
    <startEvent id="startevent1" name="Start"></startEvent>
    <endEvent id="endevent1" name="End"></endEvent>
    <serviceTask id="servicetask1" name="Service Task" activiti:class="com.mikewidgets.helloWorld.HelloWorldTask">
      <multiInstanceLoopCharacteristics isSequential="true">
        <loopCardinality>8</loopCardinality>
      </multiInstanceLoopCharacteristics>
    </serviceTask>
    <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
    <sequenceFlow id="flow2" name="" sourceRef="servicetask1" targetRef="endevent1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_Dia1">
    <bpmndi:BPMNPlane bpmnElement="Dia1" id="BPMNPlane_Dia1">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35" width="35" x="90" y="150"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35" width="35" x="430" y="300"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="servicetask1" id="BPMNShape_servicetask1">
        <omgdc:Bounds height="55" width="105" x="240" y="160"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="125" y="167"></omgdi:waypoint>
        <omgdi:waypoint x="240" y="187"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="345" y="187"></omgdi:waypoint>
        <omgdi:waypoint x="447" y="187"></omgdi:waypoint>
        <omgdi:waypoint x="447" y="300"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

frederikherema1
Star Contributor
Star Contributor
Seems like there is NO execution-listener defined in your process, am I right? Or are they added through a BPMNParseListener?

Anyway, I double-checked and I'm seeing different behavior. In my unit-test, the end-listener is called (loopCount +1) times instead of just once:

Code added to MultiInstanceTest

@Deployment(resources = {"org/activiti/engine/test/bpmn/multiinstance/MultiInstanceTest.sequentialServiceTasksWithListeners.bpmn20.xml"})
  public void testSequentialServiceTasksWithListeners() {
   
    HashMap<String, Object> variables = new HashMap<String, Object>();
    variables.put("nrOfLoops", 3);
    variables.put("startCount", 0L);
    variables.put("runCount", 0L);
    variables.put("endCount", 0L);
   
    // Start process
    String procId = runtimeService.startProcessInstanceByKey("miSequentialServiceTasks", variables).getId();
   
    Map<String, Object> variablesAfterRun = runtimeService.getVariables(procId);
    assertEquals(3L, variablesAfterRun.get("startCount"));
    assertEquals(3L, variablesAfterRun.get("runCount"));
    assertEquals(3L, variablesAfterRun.get("endCount"));
  }

<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definition"
  xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:activiti="http://activiti.org/bpmn"
  targetNamespace="Examples">
 
  <process id="miSequentialServiceTasks">
 
    <startEvent id="theStart" />
    <sequenceFlow id="flow1" sourceRef="theStart" targetRef="serviceTask" />
   
    <serviceTask id="serviceTask" name="Do stuff" activiti:expression="${execution.setVariable('runCount', execution.getVariable('runCount') + 1)}">
      <extensionElements>
         <activiti:executionListener expression="${execution.setVariable('endCount', execution.getVariable('endCount') + 1)}" event="end" />
         <activiti:executionListener expression="${execution.setVariable('startCount', execution.getVariable('startCount') + 1)}" event="start" />
      </extensionElements>
      <multiInstanceLoopCharacteristics isSequential="true">
        <loopCardinality>${nrOfLoops}</loopCardinality>
        <completionCondition>${nrOfCompletedInstances == 3}</completionCondition>
      </multiInstanceLoopCharacteristics>
    </serviceTask>
   
    <sequenceFlow id="flow3" sourceRef="serviceTask" targetRef="userTask" />
    <userTask id="userTask" />
   
    <sequenceFlow id="flow4" sourceRef="userTask" targetRef="theEnd" />
    <endEvent id="theEnd" />
   
  </process>

</definitions>


junit.framework.AssertionFailedError: expected:<3> but was:<4>
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotEquals(Assert.java:283)
at junit.framework.Assert.assertEquals(Assert.java:64)
at junit.framework.Assert.assertEquals(Assert.java:71)
at org.activiti.engine.test.bpmn.multiinstance.MultiInstanceTest.testSequentialServiceTasksWithListeners(MultiInstanceTest.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:168)
at org.activiti.engine.impl.test.PvmTestCase.runTest(PvmTestCase.java:75)
at junit.framework.TestCase.runBare(TestCase.java:134)
at org.activiti.engine.impl.test.AbstractActivitiTestCase.runBare(AbstractActivitiTestCase.java:90)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

I've created https://jira.codehaus.org/browse/ACT-1271

vram
Champ in-the-making
Champ in-the-making
My execution listener is added through the BPMNParseListener. Though, I see the variable values correctly, the end event is received by my listener only once after all the iterations.The  end event is not received after each iteration.

frederikherema1
Star Contributor
Star Contributor
Okay… Probabily the way the listener is added makes a difference. I looked into the behavior and will take this into account when fixing the related issue. Because listeners added in the process-definition do get fired x+1 times..