In many business processes, you may need to assign a task to several users in parallel. In Camunda, this is commonly achieved using a multi-instance user task configured for parallel execution. This approach transforms a single task into multiple instances dynamically, with each instance assigned to a different user from a collection that is determined at runtime.
This article explains how to model such a workflow, generate the dynamic user list, and configure task assignment using Camunda’s BPMN 2.0 extensions for multi-instance activities. The guidance below is based on the official Camunda documentation — see Task Markers for more details.
1. Model Your Workflow with a Parallel Multi-Instance User Task
To create parallel tasks, define a user task in your BPMN model and add a multiInstanceLoopCharacteristics element. This element uses the camunda:collection
and camunda:elementVariable
attributes to iterate over a collection of user IDs determined at runtime.
Below is an example BPMN snippet:
<bpmn:userTask id="Task_Review" name="Review Document">
<bpmn:multiInstanceLoopCharacteristics
isSequential="false"
camunda:collection="${userIds}"
camunda:elementVariable="currentUser">
<!-- Optional completion condition to decide when to end the multi-instance -->
<bpmn:completionCondition>${nrOfCompletedInstances == nrOfInstances}</bpmn:completionCondition>
</bpmn:multiInstanceLoopCharacteristics>
<bpmn:extensionElements>
<camunda:assignee>${currentUser}</camunda:assignee>
<!-- Additional task configurations like forms can be added here -->
</bpmn:extensionElements>
</bpmn:userTask>
Key Points:
- isSequential="false": This setting ensures that the tasks are executed in parallel.
-
camunda:collection: Resolves at runtime to a collection variable (e.g.,
userIds
) that holds the list of user IDs. -
camunda:elementVariable: Each instance will have its own variable (here,
currentUser
) that holds one user ID from the collection. - camunda:assignee: The task assignment leverages the dynamic element variable to assign the task to the correct user.
2. Generate the User List at Runtime
Before the multi-instance user task is reached in the process, you need to determine the list of users dynamically. This can be accomplished using a Service Task or a Java delegate that retrieves or calculates the list of appropriate user IDs. For instance:
Example Java Delegate:
package com.example.delegate;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import java.util.Arrays;
import java.util.List;
public class FetchUsersDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
// Example: Fetch user IDs dynamically from a database or an external service.
List<String> userIds = Arrays.asList("user1", "user2", "user3");
// Set the variable "userIds" so the multi-instance task can iterate over it.
execution.setVariable("userIds", userIds);
}
}
In your BPMN model, the service task should be placed before the multi-instance task to ensure the userIds
variable is available:
<bpmn:serviceTask id="FetchUsers" name="Fetch User IDs" camunda:class="com.example.delegate.FetchUsersDelegate" />
3. Assign Tasks Dynamically
Each instance of the multi-instance user task will receive a single element from the userIds
collection via the element variable currentUser
. The task assignment is then achieved by referencing ${currentUser}
in the task’s properties (using Camunda’s extension elements):
<camunda:assignee>${currentUser}</camunda:assignee>
Ensure that the users referenced in the collection exist in Camunda’s identity service or are synchronized with your user management system (such as LDAP or SSO).
4. Handling Task Completion
The process waits for the multi-instance to finish based on the defined completion condition. In the example above, the sample condition waits until all tasks are completed:
<bpmn:completionCondition>${nrOfCompletedInstances == nrOfInstances}</bpmn:completionCondition>
You can adjust the completion condition as needed—for instance, to continue the process when a certain percentage of tasks are completed.
5. Testing the Workflow
To test your workflow:
- Deploy the process definition to your Camunda Engine.
-
Start a new instance of the process. When starting the process, supply the
userIds
variable either through a preceding service task (as shown above) or via the REST API:
{
"variables": {
"userIds": {
"value": ["user1", "user2", "user3"],
"type": "Json"
}
}
}
-
Verify that each task is correctly assigned to the user indicated by the
currentUser
variable in each instance.
Conclusion
By leveraging the parallel multi-instance capabilities in Camunda, you can efficiently create workflows where human tasks are dynamically generated and assigned to a varying number of users at runtime. The combination of BPMN 2.0 multi-instance loop characteristics and Camunda-specific extensions (such as camunda:collection
and camunda:elementVariable
) provides a flexible approach to managing parallel human tasks.
Top comments (0)