Wednesday, February 10, 2016

Activiti 6 adds ad-hoc sub process support

With the first official release of Activiti 6 approaching we have added support for ad-hoc sub processes. It's a feature that shows the strength of the Engine refactoring we have been doing, because it's a fairly simple implementation on an Engine level. Let's have a look at what's possible with ad-hoc sub processes in Activiti 6.

We haven't updated the BPMN editor yet with the ad-hoc sub process symbols and properties, as this is an Engine feature in its current state. But the editor part will be added as well of course. So let's imagine the following embedded sub process to be ad-hoc.

The ad-hoc sub process contains two tasks without any sequence flow being defined. When a process instance is started from this process definition, an ad-hoc sub process execution is created in the Activiti Engine and no user task is created yet. For an ad-hoc sub process you can get a list of enabled activities, which refers to the activities that are available within the ad-hoc sub process to work on. So you can work on Task 1 and Task 2 in any order. With the following API call you can get a list of enabled activities from the Engine.

runtimeService.getEnabledActivitiesFromAdhocSubProcess(executionId);

This gives back a list of FlowNode objects that are enabled in the ad-hoc sub process for which the execution identifier is passed as parameter. In this example there will be two UserTask objects returned by this API call. So you can imagine a UI / application where a user can choose which task to work on next. The API call to start one of these tasks looks like this:

runtimeService.executeActivityInAdhocSubProcess(executionId, id);

So again the execution identifier of the ad-hoc sub process is provided, and in addition an identifier of the user task to select is provided as well. This identifier matches the id attribute of the user task element in the BPMN XML of the process definition. When this call is executed for Task 1 for example, the Activiti Engine will create a new user task, which will be available just like any other user task. 

An ad-hoc sub process by default can execute multiple enabled activities at the same time. This is defined with the ordering attribute in the BPMN XML definition. This means that we could also execute Task 2 in our example, while also having Task 1 active at the same time.

And what happens when Task 1 and/or Task 2 are completed. Without defining a completionCondition attribute in the BPMN XML, the Activiti Engine will not end the ad-hoc sub process execution automatically. The RuntimeService API provides the following method to complete an ad-hoc sub process when there are no active child executions (for example user tasks) anymore:

runtimeService.completeAdhocSubProcess(executionId);

After invoking this method our example process will continue to the After task activity and the ad-hoc sub process will be ended.

But invoking a method to complete an ad-hoc sub process isn't appropriate for a lot of use cases. So let's look at an BPMN XML example with a defined completion condition.

<adHocSubProcess id="adhocSubProcess" ordering="Sequential">
    
    <userTask id="subProcessTask" name="Task in subprocess" />
    <userTask id="subProcessTask2" name="Task2 in subprocess" />
      
    <completionCondition>${completed}</completionCondition>
    

</adHocSubProcess>

There are two differences with the previous example process definition. The first difference is the ordering attribute, which is set to Sequential. This means that only one of the user tasks can be executed at the same time. The Activiti Engine will not allow a second user task to be executed, when the first user task hasn't been completed yet. The second difference is the completion condition. This ad-hoc sub process will be automatically completed when the ${completed} expression evaluates to true. So, when we execute the first user task in the ad-hoc sub process and complete it together with a variable completed of true, the ad-hoc will end automatically after completing the user task.

Until now we have been demonstrating individual user tasks within an ad-hoc sub process only. But it's also possible to define individual task together with flows as well. Let's look at an example process model.


In this example Task 1 and Task 2 are enabled when the ad-hoc sub process is started by the Activiti Engine. So it's not possible to execute the other user tasks yet. When Task 1 is executed and completed, the Next task will be automatically created by the Engine, just like it would happen in a normal flow in a process definition. Using the completion condition, you can still determine when the ad-hoc sub process can be completed. And using the cancelRemainingInstances attribute it's possible to define whether the ad-hoc sub process should cancel any remaining executions / tasks when the completion condition evaluates to true. By default the Activiti Engine will cancel all other running executions / tasks, but when setting this attribute to false, the ad-hoc sub process will not complete before all executions / tasks have been ended.

The Activiti 6 Engine opens up a whole new range of dynamic behaviour in process instances. Because of its well defined execution structure and flexible API, there are a lot of new possibilities to add to the Engine. Ad-hoc sub processes is just an example as you will see more functionality appearing in Activiti 6 in the near future.

You can already play around with the ad-hoc sub process functionality on the activiti6 branch on Github (https://github.com/Activiti/Activiti/tree/activiti6). We are looking for feedback from the community about this feature and other BPMN related features you would like to see implemented in Activiti 6.