Tuesday, November 8, 2016

Flowable 6 adds ad-hoc sub process support

With the first official release of Flowable 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 Flowable 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 Flowable 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 Flowable 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 Flowable 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 Flowable 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 Flowable 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 Flowable 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 Flowable 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 Flowable 6 in the near future.

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

9 comments:

  1. Hello Tijs,

    This looks very interesting and as I think through it I have got a few questions in my mind.
    Question 1
    Say I have 1 user task(assigned to user1) followed by adhoc sub process(all tasks assigned to user2) followed by another user task(assigned to user3). Here the user2 will not be knowing when he has to look for adhoc tasks assigned to him since he will not see him in his task inbox.
    Question 2
    Even though if he knows, I think he has to check for tasks by executionId which I think is process instance id which he might not be knowing.

    Question 3
    Even if he somehow gets to know the process instance Id, I think he should get the tasks related to each process instance id every time.

    Question 4
    Looking at the details, I think all the tasks in adhoc subprocess should be assigned to a single user. Am I right here ?

    I am sure you would thought thorough all these but its just that I am not clear and would like to know.

    Thanks,
    Hari.

    ReplyDelete
  2. Hi Hari,

    1. When an enabled user task in an ad-hoc sub process is executed the normal assignment logic is performed by the Engine, so no additional logic is needed there. The interesting bit is, how to execute an enabled user task. I think it makes sense to add some assignment logic on the adhoc sub process so an assignment-like query can be executed to get the "enabled" user tasks that you are allowed to execute.

    2. An easier query solution is needed, I agree. This is the only the first stage of ad-hoc sub process functionality.

    3. Don't understand this question, can you elaborate a bit?

    4. No, user tasks can have different assignment. When an enabled user task is executed the same assignment logic as with other user tasks is executed.

    ReplyDelete
  3. Thanks for your quick reply Tijs.

    Reg Q1) Sorry, I cannot understand your answer here. In your post you said "an ad-hoc sub process execution is created in the Activiti Engine and no user task is created yet". So in my Q1, when usertask1 is completed, and since the user task 2 is not created yet as per the quoted text here. User2 will not be aware of UserTask1 completion and he will not look for enabled tasks. So my question is how will User2 know when to look for them.

    Reg Ans2) I do understand and I appreciate the efforts put in. I am sure we can see great things coming up out of this and we are waiting for them.

    Reg Q3) Say for example there are 10 instances of a process(which has adhoc sub process in it). Now when a user say User2 as per my example has to get the enabled tasks, he has to pass the executionid to the below snippet.

    runtimeService.getEnabledActivitiesFromAdhocSubProcess(executionId);

    So I think its not easy to get all the enabled tasks of all the process instances. The way I see is, he has to iterate through all the process instances and get the enabled tasks.

    To complicate the situation more, say for example there are 4 BPM's and 10+ instances of each of them which has adhoc sub process in them. And if User2 is involved in all 4 BPM's, to get a list of all enabled tasks in all the 4 BPM's 10+ instances could be a challenging.

    Is there an easier way to get them ?

    Reg Q4) Ok.

    Thanks,
    Hari.

    ReplyDelete
  4. Hi Hari,

    1. You need an additional query to look for enabled tasks for a user. So when you would you do this query user2 can be made aware by adding it to the task list or some other place.

    3. Not yet, but you are right that we need to a specific API to make this easy to do.

    ReplyDelete
  5. how change the default databse in the activiti 6 Mysql to h2 Or how to connect activiti with mysql step by step

    ReplyDelete
    Replies
    1. Hi Ramzi,

      If you are having tomcat 9.0 in your system you can follow below path:
      Tomcat 9.0\webapps\activiti-explorer\WEB-INF\classes (For explorer)
      Tomcat 9.0\webapps\activiti-rest\WEB-INF\classes (For rest)
      Make your DB and host name edited as per your requirement

      Thanks,
      Saurabh

      Delete
  6. Hi
    This new Element has support for callActivity, I mean, can I put an callAcitvity inside the Ad Doc subprocess
    Thanks :D

    ReplyDelete
  7. Marco van Zwetselaar (zwets)August 20, 2017 at 9:57 AM

    Hi Tijs, I just tried modeling your example (using the modeler in 6.2.0-SNAPSHOT), but when I try to publish the App I get this error:

    "org.flowable.bpmn.exceptions.XMLException: cvc-complex-type.2.4.d: Invalid content was found starting with element 'userTask'. No child element is expected at this point."

    Would this mean the subprocess needs a (none) start event? Note the Userguide in 8.6.1 mentions "A Sub-Process can only have one none start event, no other start event types are allowed. A Sub-Process must at least have one end event. Note that the BPMN 2.0 specification allows the omission of the start and end events in a Sub-Process, but the current Flowable implementation does not support this."

    ReplyDelete
  8. Marco van Zwetselaar (zwets)August 20, 2017 at 11:52 AM

    I have added a post on the Flowable forum[1] so as to have this documented 'centrally'.

    [1] https://forum.flowable.org/t/adhoc-task-fails-to-deploy/873

    ReplyDelete