Executing Sub process using Call Activity Parallel Async mode not truely parallel

Hi,
I have a scenario where I am creating multiinstance parallel call activity with collection size of 10.
Fields of call activities are

<callActivity id=“CallActivity_tlu34o” name=“Process Sub” flowable:calledElement=“Suprocess_Id” flowable:calledElementType=“key” flowable:fallbackToDefaultTenant=“true” flowable:completeAsync=“true” flowable:async=“true” flowable:exclusive=“true”>multiInstanceLoopCharacteristics isSequential=“false” flowable:collection=“${studentList}” flowable:elementVariable=“student”/>

To achieve multi threaded true parallel, async is marked as true. But without completeAsync=“true” and exclusive=“true” I was getting FlowableOptimisticLockException even without any activity in subprocess async. So I make both completeAsync and exclusive as true to avoid FlowableOptimisticLockException.

But once I made exclusive=true, not all 10 threads are executing in parallel. I have created custom AsyncListenableTaskExecutor taskExector bean with ThreadPool size of 100 and DB(postgres) max connection as 300. So there is no bottleneck.

Any suggestion how I can achieve true parallellism can achieve this.

Hey @prasanta,

When you set flowable:exclusive=“true” you are telling Flowable that it should run every parallel execution exclusively, i.e. you are telling Flowable not to execute the things truly in parallel.

In order to achieve a true async parallel execution you’ll have to set that flag to false (flowable:exclusive=“false”).

Cheers,
Filip

Hi @filiphr I really appreciate your response.
When I am setting flowable:exclusive=“false” on multiinstance call activity, I am getting either flowableOptimistingLockException(for ex. activity ‘CallActivity_tlu34o’ - parent ‘79f9b36e-b34b-11ed-8cca-9c2dcd7f8b9e’ was updated by another transaction concurrently) or foreign key violation by one asyn thread(error-insert or update on table “act_ru_variable” violates foreign key constraint “act_fk_var_exe” Key (execution_id_)=(0dcec894-b37e-11ed-ba76-9c2dcd7f8b9e) is not present in table “act_ru_execution”.
In both cases I have marked completeAsync as true

Can you please help here

In order to avoid the optimistic locking exceptions and to properly get the variables you’ll need to use variable aggregation.

Have a look at Multi Instance Variable Aggregation for more details.

Cheers,
Filip

1 Like

Hi @filiphr Now I am not getting optimistic exception. However I am getting below exception sometimes–
2023-02-25 21:38:42.972 [ERROR] : [async-tp2] org.flowable.common.engine.impl.interceptor.CommandContext:logException - Error while closing command context
org.apache.ibatis.exceptions.PersistenceException:

Error updating database. Cause: org.postgresql.util.PSQLException: ERROR: insert or update on table “act_ru_variable” violates foreign key constraint “act_fk_var_exe”

Detail: Key (execution_id_)=(ac72747e-b526-11ed-951d-9c2dcd7f8b9e) is not present in table “act_ru_execution”.

The error may exist in org/flowable/variable/service/db/mapping/entity/VariableInstance.xml

The error may involve org.flowable.variable.service.impl.persistence.entity.VariableInstanceEntityImpl.bulkInsertVariableInstance-Inline

The error occurred while setting parameters

SQL: INSERT INTO ACT_RU_VARIABLE…

Cause: org.postgresql.util.PSQLException: ERROR: insert or update on table “act_ru_variable” violates foreign key constraint “act_fk_var_exe”

Detail: Key (execution_id_)=(ac72747e-b526-11ed-951d-9c2dcd7f8b9e) is not present in table “act_ru_execution”.
and
2023-02-25 21:39:44.021 [ERROR] : [async-tp73] org.flowable.common.engine.impl.interceptor.CommandContext:logException - Error while closing command context
org.apache.ibatis.exceptions.PersistenceException:

Error updating database. Cause: org.postgresql.util.PSQLException: ERROR: update or delete on table “act_ru_execution” violates foreign key constraint “act_fk_var_exe” on table “act_ru_variable”

Detail: Key (id_)=(abad7633-b526-11ed-951d-9c2dcd7f8b9e) is still referenced from table “act_ru_variable”.

The error may exist in org/flowable/db/mapping/entity/Execution.xml

The error may involve org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl.deleteExecution-Inline

The error occurred while setting parameters

SQL: delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ?

Cause: org.postgresql.util.PSQLException: ERROR: update or delete on table “act_ru_execution” violates foreign key constraint “act_fk_var_exe” on table “act_ru_variable”

Detail: Key (id_)=(abad7633-b526-11ed-951d-9c2dcd7f8b9e) is still referenced from table “act_ru_variable”.

Call Activity configuration
callActivity id=… name=“Process ClaimList” flowable:async=“true” flowable:exclusive=“false” flowable:completeAsync=“true” calledElement=“App-ChildLogin” flowable:sameDeployment=“true” flowable:fallbackToDefaultTenant=“true”
extensionElements>
flowable:in source=“baseUrl” target=“baseUrl”></flowable:in>
flowable:out source=“sessionExecutionStatus” target=“sessionExecutionStatus”></flowable:out>
extensionElements>
multiInstanceLoopCharacteristics isSequential=“false” flowable:collection=“${claimListForProcess}” flowable:elementVariable=“claimList”>
extensionElements>
<flowable:variableAggregation target=“sessionsStatus” delegateExpression=“#{varAggregator}”>
variable sourceExpression=“${sessionExecutionStatus}” target=“status”>
flowable:variableAggregation>
extensionElements>
multiInstanceLoopCharacteristics>

Thank you in advance.

Hey @prasanta,

I see that you have a custom variable aggregator. In order for us to be able to look into this we would need the entire BPMN XML and also your custom variable aggregator.

Cheers,
Filip

Hi @filiphr Sharing processes as below

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:bpmndc="http://www.omg.org/spec/BPMN/20100524/DC" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="s">
	<process id="AdjudicationApp-AdjParentClaimList-s" name="AdjParentClaimList" isExecutable="true">
		<extensionElements>
			<flowable:eventListener events="PROCESS_STARTED" flowable:delegateExpression="${ProcessEventListener}"/>
			<flowable:eventListener events="ACTIVITY_STARTED" flowable:delegateExpression="${ProcessActivityListener}"/>
			<flowable:eventListener events="ACTIVITY_COMPLETED" flowable:delegateExpression="${ProcessActivityListener}"/>
			<flowable:eventListener events="ACTIVITY_CANCELLED" flowable:delegateExpression="${ProcessActivityListener}"/>
			<flowable:eventListener events="PROCESS_CREATED" flowable:delegateExpression="${ProcessEventListener}"/>
			<flowable:eventListener events="PROCESS_COMPLETED" flowable:delegateExpression="${ProcessEventListener}"/>
			<flowable:eventListener events="PROCESS_CANCELLED" flowable:delegateExpression="${ProcessEventListener}"/>
			<flowable:eventListener events="TASK_ASSIGNED" flowable:delegateExpression="${ProcessTaskListener}"/>
			<flowable:eventListener events="TASK_COMPLETED" flowable:delegateExpression="${ProcessTaskListener}"/>
			<flowable:eventListener events="TASK_CREATED" flowable:delegateExpression="${ProcessTaskListener}"/>
			<flowable:eventListener events="TIMER_FIRED" flowable:delegateExpression="${ProcessTimerListener}"/>
			<flowable:eventListener events="TIMER_SCHEDULED" flowable:delegateExpression="${ProcessTimerListener}"/>
			<flowable:eventListener events="VARIABLE_CREATED" flowable:delegateExpression="${ProcessVariableListener}"/>
			<flowable:eventListener events="VARIABLE_DELETED" flowable:delegateExpression="${ProcessVariableListener}"/>
			<flowable:eventListener events="VARIABLE_UPDATED" flowable:delegateExpression="${ProcessVariableListener}"/>
			<flowable:historyLevel xmlns:flowable="http://flowable.org/bpmn">
				<![CDATA[full]]>
			</flowable:historyLevel>
		</extensionElements>
		<dataObject id="new_data_object_1" name="baseUrl" itemSubjectRef="xsd:string"/>
		<dataObject id="new_data_object_2" name="sessionCount" itemSubjectRef="xsd:string"/>
		<scriptTask id="ScriptTask_bgwmdn" name="Claim Seggregation" scriptFormat="JavaScript">
			<script>
				<![CDATA[var claimListVar = claimList.getClaimListResponseType.icn;
var i = 0;
var j = j1 = java.lang.Math.floor(claimListVar.size()/sessionCount);//10
java.lang.System.out.println("++++++++++++++Total claims to be processed::"+claimListVar.size()+" by "+sessionCount+" sessions");
var claimListForProcess = new java.util.ArrayList();
while(i < sessionCount)//this comes 320 and session 30
 { 
    var k = 0;	
	 if(i == sessionCount-1){
        j+=claimListVar.size()%sessionCount;
    }   
    var claimListPerSession = new java.util.ArrayList();
    while(k<j){
        if(i < sessionCount-1 && claimListVar[i*j+k]){
			claimListPerSession.add(claimListVar[i*j+k].toString());
		  }
		  
		  else if(i == sessionCount-1 && claimListVar[i*j1+k]){
			claimListPerSession.add(claimListVar[i*j1+k].toString());
		  } 
        k++;
    }	
	if(claimListPerSession.size()>0){
		claimListForProcess.add(claimListPerSession);
	}    
    i++; 
 } 
 execution.setVariable("claimListForProcess", claimListForProcess);
  java.lang.System.out.printf("Current Thread=%s claimListForProcess=%s", threadName, claimListForProcess);]]>
			</script>
		</scriptTask>
		<scriptTask id="ScriptTask_1hqp4q0" name="Post Process Login" scriptFormat="JavaScript">
			<script>
				<![CDATA[java.lang.System.out.println("+++++++++job endtime::"+java.time.LocalDateTime.now());]]>
			</script>
		</scriptTask>
		<endEvent id="EndEvent_1lev7l" name="End"/>
		<startEvent id="StartEvent_15cehbe" name="Start"/>
		<callActivity id="CallActivity_tlu34o" name="Process ClaimList" flowable:calledElement="AdjudicationApp-AdjChildLogin-s" flowable:calledElementType="key" flowable:fallbackToDefaultTenant="true" flowable:completeAsync="true" flowable:async="true" flowable:exclusive="false">
			<extensionElements>
				<flowable:in source="baseUrl" target="baseUrl"/>
				<flowable:in source="claimListForOneRobot" target="claimListForOneRobot"/>
			</extensionElements>
			      <multiInstanceLoopCharacteristics isSequential="false" flowable:collection="${claimListForProcess}" flowable:elementVariable="claimListForOneRobot">
        <extensionElements>
          <flowable:variableAggregation target="sessionsStatus" delegateExpression="#{varAggregator}">
            <variable sourceExpression="${sessionExecutionStatus}" target="status"></variable>
          </flowable:variableAggregation>
        </extensionElements>
      </multiInstanceLoopCharacteristics>
		</callActivity>
		<serviceTask id="HttpTask_13tps0k" name="Get Session Id" flowable:type="http" flowable:parallelInSameTransaction="false">
			<extensionElements>
				<flowable:executionListener event="start" class="com.sys.services.processengine.scripttask.ProcessEngineSecureJavascriptExecutionListener">
					<flowable:field name="script">
						<flowable:string>
							<![CDATA[var threadName = java.lang.Thread.currentThread().getName();
execution.setVariable("threadName", threadName);
java.lang.System.out.println("+++++++++job starttime::"+java.time.LocalDateTime.now());]]>
						</flowable:string>
					</flowable:field>
					<flowable:field name="language" stringValue="javascript"/>
				</flowable:executionListener>
				<flowable:executionListener event="end" class="com.sys.services.processengine.scripttask.ProcessEngineSecureJavascriptExecutionListener">
					<flowable:field name="script">
						<flowable:string>
							<![CDATA[java.lang.System.out.println("SessionId obtained::"+sessionId.createResponse.sessionId);]]>
						</flowable:string>
					</flowable:field>
					<flowable:field name="language" stringValue="javascript"/>
				</flowable:executionListener>
				<flowable:field name="saveResponseVariableAsJson">
					<flowable:string>
						<![CDATA[true]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestHeaders">
					<flowable:string>
						<![CDATA[Authorization: Basic XXXX==]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="responseVariableName">
					<flowable:string>
						<![CDATA[sessionId]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestUrl">
					<flowable:expression>
						<![CDATA[${baseUrl}/create]]>
					</flowable:expression>
				</flowable:field>
				<flowable:field name="requestMethod">
					<flowable:string>
						<![CDATA[GET]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestTimeout">
					<flowable:string>
						<![CDATA[5000]]>
					</flowable:string>
				</flowable:field>
			</extensionElements>
		</serviceTask>
		<serviceTask id="HttpTask_1uytu7" name="GetClaimLIst" flowable:type="http" flowable:parallelInSameTransaction="false">
			<extensionElements>
				<flowable:executionListener event="end" class="com.sys.services.processengine.scripttask.ProcessEngineSecureJavascriptExecutionListener">
					<flowable:field name="script">
						<flowable:string>
							<![CDATA[java.lang.System.out.println("ClaimList obtained::"+claimList.getClaimListResponseType.icn);]]>
						</flowable:string>
					</flowable:field>
					<flowable:field name="language" stringValue="javascript"/>
				</flowable:executionListener>
				<flowable:field name="saveResponseVariableAsJson">
					<flowable:string>
						<![CDATA[true]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestHeaders">
					<flowable:string>
						<![CDATA[Authorization: Basic XXXX==
Content-Type: application/json
Connection: keep-alive]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="responseVariableName">
					<flowable:string>
						<![CDATA[claimList]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestBody">
					<flowable:string>
						<![CDATA[{"getClaimListRequest": {"uid": "java2","pwd": "java2","region": "01","routeID": "DCS,M201","setVisible": "false","debug": "true","theradID": "1"}}]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestUrl">
					<flowable:expression>
						<![CDATA[${baseUrl}/getClaimList/${sessionId.createResponse.sessionId}]]>
					</flowable:expression>
				</flowable:field>
				<flowable:field name="requestMethod">
					<flowable:string>
						<![CDATA[POST]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestBodyEncoding">
					<flowable:string>
						<![CDATA[UTF-8]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestTimeout">
					<flowable:string>
						<![CDATA[10000]]>
					</flowable:string>
				</flowable:field>
			</extensionElements>
		</serviceTask>
		<serviceTask id="HttpTask_h66cmr" name="Dispose Session Id" flowable:type="http" flowable:parallelInSameTransaction="false">
			<extensionElements>
				<flowable:executionListener event="end" class="com.sys.services.processengine.scripttask.ProcessEngineSecureJavascriptExecutionListener">
					<flowable:field name="script">
						<flowable:string>
							<![CDATA[java.lang.System.out.println("Session Id::"+sessionId.createResponse.sessionId+" is disposed");]]>
						</flowable:string>
					</flowable:field>
					<flowable:field name="language" stringValue="javascript"/>
				</flowable:executionListener>
				<flowable:field name="saveResponseVariableAsJson">
					<flowable:string>
						<![CDATA[false]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestUrl">
					<flowable:expression>
						<![CDATA[${baseUrl}/dispose/${sessionId.createResponse.sessionId}]]>
					</flowable:expression>
				</flowable:field>
				<flowable:field name="requestMethod">
					<flowable:string>
						<![CDATA[GET]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestTimeout">
					<flowable:string>
						<![CDATA[5000]]>
					</flowable:string>
				</flowable:field>
			</extensionElements>
		</serviceTask>
		<sequenceFlow id="SequenceFlow_1d7iry7" name="" sourceRef="StartEvent_15cehbe" targetRef="HttpTask_13tps0k"/>
		<sequenceFlow id="SequenceFlow_1fmd3an" name="" sourceRef="HttpTask_13tps0k" targetRef="HttpTask_1uytu7"/>
		<sequenceFlow id="SequenceFlow_lkcozp" name="" sourceRef="HttpTask_1uytu7" targetRef="HttpTask_h66cmr"/>
		<sequenceFlow id="SequenceFlow_1oj951m" name="" sourceRef="HttpTask_h66cmr" targetRef="ScriptTask_bgwmdn"/>
		<sequenceFlow id="SequenceFlow_1ird8xg" name="" sourceRef="ScriptTask_bgwmdn" targetRef="CallActivity_tlu34o"/>
		<sequenceFlow id="SequenceFlow_vg9a9v" name="" sourceRef="CallActivity_tlu34o" targetRef="ScriptTask_1hqp4q0"/>
		<sequenceFlow id="SequenceFlow_f3fzak" name="" sourceRef="ScriptTask_1hqp4q0" targetRef="EndEvent_1lev7l"/>
	</process>
</definitions>

Child process

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:bpmndc="http://www.omg.org/spec/BPMN/20100524/DC" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="s">
	<process id="AdjudicationApp-AdjChildLogin-s" name="AdjChildLogin" isExecutable="true">
		<extensionElements>
			<flowable:eventListener events="PROCESS_STARTED" flowable:delegateExpression="${ProcessEventListener}"/>
			<flowable:eventListener events="ACTIVITY_STARTED" flowable:delegateExpression="${ProcessActivityListener}"/>
			<flowable:eventListener events="ACTIVITY_COMPLETED" flowable:delegateExpression="${ProcessActivityListener}"/>
			<flowable:eventListener events="ACTIVITY_CANCELLED" flowable:delegateExpression="${ProcessActivityListener}"/>
			<flowable:eventListener events="PROCESS_CREATED" flowable:delegateExpression="${ProcessEventListener}"/>
			<flowable:eventListener events="PROCESS_COMPLETED" flowable:delegateExpression="${ProcessEventListener}"/>
			<flowable:eventListener events="PROCESS_CANCELLED" flowable:delegateExpression="${ProcessEventListener}"/>
			<flowable:eventListener events="TASK_ASSIGNED" flowable:delegateExpression="${ProcessTaskListener}"/>
			<flowable:eventListener events="TASK_COMPLETED" flowable:delegateExpression="${ProcessTaskListener}"/>
			<flowable:eventListener events="TASK_CREATED" flowable:delegateExpression="${ProcessTaskListener}"/>
			<flowable:eventListener events="TIMER_FIRED" flowable:delegateExpression="${ProcessTimerListener}"/>
			<flowable:eventListener events="TIMER_SCHEDULED" flowable:delegateExpression="${ProcessTimerListener}"/>
			<flowable:eventListener events="VARIABLE_CREATED" flowable:delegateExpression="${ProcessVariableListener}"/>
			<flowable:eventListener events="VARIABLE_DELETED" flowable:delegateExpression="${ProcessVariableListener}"/>
			<flowable:eventListener events="VARIABLE_UPDATED" flowable:delegateExpression="${ProcessVariableListener}"/>
			<flowable:historyLevel xmlns:flowable="http://flowable.org/bpmn">
				<![CDATA[full]]>
			</flowable:historyLevel>
		</extensionElements>
		<scriptTask id="ScriptTask_132l5v8" name="Login Claim List" scriptFormat="JavaScript">
			<script>
				<![CDATA[var threadName = java.lang.Thread.currentThread().getName();
execution.setVariable("threadName", threadName);
java.lang.System.out.printf("\nClaimList=%s and PI=%s under thread=%s\n",
claimListForOneRobot, execution.getProcessInstanceId(), threadName);]]>
			</script>
		</scriptTask>
		<endEvent id="EndEvent_1ncnf5z" name="End"/>
		<callActivity id="CallActivity_1n9d29j" name="Process One claim" flowable:calledElement="AdjudicationApp-AdjChildProcessOneClaim-s" flowable:calledElementType="key" flowable:fallbackToDefaultTenant="true" flowable:completeAsync="false" flowable:async="false" flowable:exclusive="false">
			<extensionElements>
				<flowable:in source="sessionId" target="sessionId"/>
				<flowable:in source="baseUrl" target="baseUrl"/>
				<flowable:in source="claimId" target="claimId"/>
			</extensionElements>
			<multiInstanceLoopCharacteristics isSequential="true" flowable:collection="${claimListForOneRobot}" flowable:elementVariable="claimId"/>
		</callActivity>
		<startEvent id="StartEvent_7m3dme" name="Start"/>
		<serviceTask id="HttpTask_alwhds" name="Login" flowable:type="http" flowable:parallelInSameTransaction="false">
			<extensionElements>
				<flowable:executionListener event="end" class="com.sys.services.processengine.scripttask.ProcessEngineSecureJavascriptExecutionListener">
					<flowable:field name="script">
						<flowable:string>
							<![CDATA[// java.lang.System.out.printf("\nCurrent Thread=%s login Successful in Child Login\n",threadName);]]>
						</flowable:string>
					</flowable:field>
					<flowable:field name="language" stringValue="javascript"/>
				</flowable:executionListener>
				<flowable:field name="saveResponseVariableAsJson">
					<flowable:string>
						<![CDATA[true]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestHeaders">
					<flowable:string>
						<![CDATA[Authorization: Basic XXXX==]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="responseVariableName">
					<flowable:string>
						<![CDATA[loginResponse]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestUrl">
					<flowable:expression>
						<![CDATA[${baseUrl}/login/${sessionId}]]>
					</flowable:expression>
				</flowable:field>
				<flowable:field name="requestMethod">
					<flowable:string>
						<![CDATA[POST]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestTimeout">
					<flowable:string>
						<![CDATA[5000]]>
					</flowable:string>
				</flowable:field>
			</extensionElements>
		</serviceTask>
		<serviceTask id="HttpTask_9qfsdy" name="Get session Id for one robot" flowable:type="http" flowable:parallelInSameTransaction="false">
			<extensionElements>
				<flowable:executionListener event="end" class="com.sys.services.processengine.scripttask.ProcessEngineSecureJavascriptExecutionListener">
					<flowable:field name="script">
						<flowable:string>
							<![CDATA[java.lang.System.out.printf("Current thread=%s obtains sessionId=%s in child Login",threadName,sessionId.createResponse.sessionId);
execution.setVariable("sessionId", sessionId.createResponse.sessionId);]]>
						</flowable:string>
					</flowable:field>
					<flowable:field name="language" stringValue="javascript"/>
				</flowable:executionListener>
				<flowable:field name="saveResponseVariableAsJson">
					<flowable:string>
						<![CDATA[true]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestHeaders">
					<flowable:string>
						<![CDATA[Authorization: Basic XXXX==]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="responseVariableName">
					<flowable:string>
						<![CDATA[sessionId]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestUrl">
					<flowable:expression>
						<![CDATA[${baseUrl}/create]]>
					</flowable:expression>
				</flowable:field>
				<flowable:field name="requestMethod">
					<flowable:string>
						<![CDATA[GET]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestTimeout">
					<flowable:string>
						<![CDATA[5000]]>
					</flowable:string>
				</flowable:field>
			</extensionElements>
		</serviceTask>
		<serviceTask id="HttpTask_43avlw" name="Dispose Session Id for this rebot" flowable:type="http" flowable:parallelInSameTransaction="false">
			<extensionElements>
				<flowable:executionListener event="end" class="com.sys.services.processengine.scripttask.ProcessEngineSecureJavascriptExecutionListener">
					<flowable:field name="script">
						<flowable:string>
							<![CDATA[
java.lang.System.out.printf("\n======Execution completed by PI=%s under thread=%s=======\n", execution.getProcessInstanceId(),threadName);]]>
						</flowable:string>
					</flowable:field>
					<flowable:field name="language" stringValue="javascript"/>
				</flowable:executionListener>
				<flowable:field name="saveResponseVariableAsJson">
					<flowable:string>
						<![CDATA[true]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestHeaders">
					<flowable:string>
						<![CDATA[Authorization: Basic XXXX==]]>
					</flowable:string>
				</flowable:field>
				<flowable:field name="requestUrl">
					<flowable:expression>
						<![CDATA[${baseUrl}/dispose/${sessionId}]]>
					</flowable:expression>
				</flowable:field>
				<flowable:field name="requestMethod">
					<flowable:string>
						<![CDATA[GET]]>
					</flowable:string>
				</flowable:field>
			</extensionElements>
		</serviceTask>
		<sequenceFlow id="SequenceFlow_1h5l640" name="" sourceRef="HttpTask_9qfsdy" targetRef="HttpTask_alwhds"/>
		<sequenceFlow id="SequenceFlow_1rme8sd" name="" sourceRef="HttpTask_alwhds" targetRef="CallActivity_1n9d29j"/>
		<sequenceFlow id="SequenceFlow_1w0mbxe" name="" sourceRef="CallActivity_1n9d29j" targetRef="HttpTask_43avlw"/>
		<sequenceFlow id="SequenceFlow_4dcdqf" name="" sourceRef="HttpTask_43avlw" targetRef="EndEvent_1ncnf5z"/>
		<sequenceFlow id="SequenceFlow_mkvau8" name="" sourceRef="StartEvent_7m3dme" targetRef="ScriptTask_132l5v8"/>
		<sequenceFlow id="SequenceFlow_pkbioz" name="" sourceRef="ScriptTask_132l5v8" targetRef="HttpTask_9qfsdy"/>
	</process>
</definitions>

Var Aggregrator(We are using custom json type. Hence changing to that type.

@Component("varAggregator")
public class ProcessEngineJsonVarAggregator extends org.flowable.engine.impl.delegate.JsonVariableAggregator {
    public ProcessEngineJsonVarAggregator(ProcessEngineConfigurationImpl processEngineConfiguration) {
        super(processEngineConfiguration);
    }
    @Override
    public Object aggregateMultiVariables(DelegateExecution execution, List<? extends VariableInstance> instances, VariableAggregatorContext context) {
        ObjectMapper objectMapper = this.processEngineConfiguration.getObjectMapper();
        ArrayNode arrayNode = objectMapper.createArrayNode();
        Iterator var6 = instances.iterator();

        while(var6.hasNext()) {
            VariableInstance instance = (VariableInstance)var6.next();
            try {
                arrayNode.add(objectMapper.readTree(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(instance.getValue())));
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }
        return arrayNode;
    }
}

Custom json type

public class JsVariableType extends org.flowable.variable.service.impl.types.JsonType {
    private static final Logger LOGGER = LoggerFactory.getLogger(JsVariableType.class);
    public static final String TYPE_NAME = "jsType";
    protected ObjectMapper objectMapper;

    public JsVariableType(int maxLength, ObjectMapper objectMapper, boolean trackObjects) {
        super(maxLength, objectMapper, trackObjects);
        this.objectMapper = objectMapper;
    }

    @Override
    public boolean isCachable(){
        return false;
    }

    @Override
    public String getTypeName() {
        return TYPE_NAME;
    }

    @Override
    public boolean isAbleToStore(Object value) {
        return value instanceof List || value instanceof Map || value instanceof JsonNode;
    }

    @Override
    public void setValue(Object value, ValueFields valueFields) {
        JsonNode jsonNode = objectMapper.convertValue(value, JsonNode.class);
        super.setValue(jsonNode, valueFields);
    }

    @Override
    public Object getValue(ValueFields valueFields) {
        Object result = super.getValue(valueFields);

        LOGGER.debug("result={}", result);

        if (result instanceof Map || result instanceof List)
            return result;
        else if (result instanceof ObjectNode) {
            return objectMapper.convertValue(result, Map.class);
        } else if (result instanceof ArrayNode) {
            return objectMapper.convertValue(result, List.class);
        } else
            return result;
    }
}

Hi @filiphr Could you get a chance to look into this?
Also one more observation- Even with completeAsync=true and varAggregator on call activity I am getting FlowableOptimisticLockException sometimes.

So make completeAsync=false/true has no no effect on FlowableOptimisticException sometimes. Ofcourse using completeAsync=false makes.

What should be your suggestion on var aggregator and completeAsync on Call Activity(parallel, async=true, exclusive=false)?

Hi @filiphr,
As I am using async call activity, do I need to mark that completeAsync true to avoid FlowableOpimisticLockException? Or VarAggregator is enough? I observed when completeAsync is true, a new job async-complete is created for each child process instance but still getting OptimisticLockException. So is VarAggregator mandatory to avoid OptimisticLockException having process with parallel Multi Instance Call Activity?

Please confirm.

Hi there. I’m looking at Flowable reliability and support to evaluate its implementation in a critical system.

I’m worried about finding bugs like this one that have no answers and is still open after a long time. Is there a rationale behind this?

I saw you posted a similar comment on

and also on Different behaviour between parallel and inclusive gateways · Issue #1741 · flowable/flowable-engine · GitHub
and Bad behavior using Parallel Gateway with 2 end events · Issue #3577 · flowable/flowable-engine · GitHub

This is the open source community forum, where the whole community discusses various things around Flowable. It is by no means a bug tracker nor an obligation to contributors.

What’s the goal of posting this message on various places? If you want to have a discussion please create a new forum post or send me a private message.

For Parallel Call Activity with Async=true, completeAsync=true, excluse=false we need to ensure either all child instances completes normally or completion condition is met for prematured call activity complete.
Also we need MultiInstance variable aggregator in order to avoid FlowableOptimisticLocking exception.
This means there must be all activity in child process must handle error and ends normally unless completion condition says something else.

I am looking for a solution on how we should handle an error on this case for a child instance which is executiing as async job and may fail. How can I ensure other 99 child instances completes normally and Call Activity on parent level completes and execution continues

Hi Joram, I can’t find a PM facility on this forum. My question’s meaning is self-explanatory: I’m trying to understand if Flowable is maintained at a pace that will allow me to use it in a critical application or if I should look to a different solution.
I posted my questions on the threads that appeared to be critical issues, trying to understand why those are still unanswered/unresolved. Posting a generic thread didn’t seem appropriate to me.
Please feel free to answer me privately as I can’t find a way to do so here (maybe I’m just blind… no idea).