Oh, I think it’s another problem about the behavior of multi-instance activity (which I want to ask in a new topic).
I want to set a variable for the scope of multi-instance body using setVariableLocal() method at the execution listener. I want to access that variable as the completionCondition of the multi-instance activity
Unfortunately, the variable is created in the scope of the inner activity
The scope that groups all the inner instances has by convention the id <id_of_mi_activity>#multiInstanceBody. So you could try to use that to make a variable available in the scope that groups all the inner activity instances.
I use the execution.getCurrentActivityId() and append it with #multiInstanceBody string. But when I try without the string appended, it fails. So what is the expected form of activityId?
*as a note, I put that code as an execution listener of a multi-instance activity with event type:start. It’s different with the code I shared which is the listener is the property of a start event of a multi-instance subprocess
Additionally: the activityId need to be unique for activity instance (appended unique number, something like mi_activity#multiInstanceBody:10253)? If not, how do the process engine differ between instances of parallel multi-instance?
I checked on my process instance with camunda cockpit, on variables tab:
multi-instance body scope is written with my_activity#multiInstanceBody, but the popping text (when hover the mouse in) shows mi_activity#multiInstanceBody:10253
multi-instance inner acticity scope (in my case, it’s a subprocess) is written with SubProcess (SubProce...), and the popping text shows mi_activity:10262
and when I click it, the filter area shows me a criteria with form like this:
Activity Instance ID = mi_activity#multiInstanceBody:10253
We must distinguish between activity ID and activity instance ID here.
Activity ID is the ID of the BPMN element as defined in the XML. This is returned by execution.getCurrentActivityId(). In a process instance, you can have many instances per activity (think about modeling a loop, multi-instance, etc.). That’s why every such instance has an id, the activity instance id accessible via execution.getActivityInstanceId(). Both, activities and activity instances are organized hierarchically according to the BPMN definition.
The setVariable API we are discussing here takes activity IDs as its parameter, not activity instance IDs. When you call setVariable("key", "value", "activityA"), this means that the variable will be set on the next higher instance of activity activityA. This instance is always unique in this context, because there can’t be two parent/grandparent instances of the same activity.
For multi-instance, we have the “magic” activity with ID <actual_activity_id>#multiInstanceBody. This is not represented explicitly in the BPMN XML, but is generated by the process engine. It can be understood like an embedded subprocess that contains the actual activity. This is not something we made up entirely, but somewhat covered by the BPMN specification. See https://blog.camunda.org/post/2015/06/why-we-re-implemented-bpmn-multi/ for details.
When Task is executed, we have three activity instances organized in a hierarchy:
Process Instance 10 (instance of Process Definition)
^
|
Subprocess Instance 11 (instance of Subprocess)
^
|
Task Instance 12 (instance of Task)
Assume we call setVariable("key", "value", "Subprocess") API in the context of task instance 12. Then the API traverses the path from instance 12 upwards to the root until it finds an instance of Subprocess and sets the variable there. That’s what I mean with next higher instance. It stops searching once it finds the first such instance, because there cannot be another instance of Subprocess in that path. Of course, the overall tree can have multiple instances of Subprocess, but each path from a leaf to the root can contain at most one such instance.
Task_09wzlbx:5467d99f-bbca-11e8-a5b2-ace2d3a04152#multiInstanceBody is not an execute id but an activity instance id, so this request will not work anyway. On top of that, I guess the # symbol also messes up the URL unless you encode it properly.
Use a unique key for the variable within a multiInstance Process.
You can do a “jugaad (a flexible approach to solving a problem)” :
resolve/complete a task with the variable name eg testVar using rest api.
Use the code below to save a copy of the variable’s last known value at activity scope
Thanks for your response Udit. I ended up doing a similar thing.
Added a process instance variable through rest api, and then use that to post it to sub-process scope.
works for now.
@thorben, I am not sure how #multiInstanceBody should be used. Let’s use the diagram you posted in this diagram. suppose I am in Task (task id = 100) now, and I want to create a variable which can be accessed in the Subprocess(parallel mulit instance) scope. Is it right that the code be like:
The third parameter must have the following format: <activity ID in BPMN XML>#multiInstanceBody. So let’s say the ID of the activity named Task is task, then the parameter value should be task#multiInstanceBody.