So I have this need to implement PARALLEL multi-instance call activity in my project.
This call activity runs on a collection of items (it ‘creates’ those items), but these items depend on each other’s existence in some way, meaning that one subprocess has to finish before another one starts, BUT for items that do not depend on any other item, the execution should happen in parallel.
The situation is such that some instances should begin execution in parallel and some should do some polling to wait for the other(s) to complete in order for them to start (which in turn might trigger something else to start).
Now, this ‘waiting’ could be implemented in the subprocess before any tasks take place, implementing the ‘wait’ task before others. This means all subprocesses are going to start execution in parallel, but some will not get past this ‘wait’ task, and just repeatedly check if the items it depends on are completed. The problem is how to check if the whole process of an item is completed? The item is created mid-process, but there are other tasks that should still complete to consider this item fully created. Meaning I cannot check if it is created, because that would not mean the process has ended.
Is there some design in flowable, which can help me achieve something like this by design?
What are my options, here? Is there a neater way to achieve this?
We have the same situation here. We are about to extend the default ParallelMultiInstanceBehavior and to write a custom logic which makes the above description possible - as this is the recommended approach by the Flowable guys (as far as I saw some posts in the forum).
We have another preposition which makes this situation more clear and easy-extensible. In my opinion, it will be great if there could be a way to tell to the CallActivity what is its behavior. For now, the only supported behaviors are Sequential and Parallel, what if we want to add Parallel between dependencies as in this case? Here is the preposition:
- Create a new property which will be added to the activities(CallActivity, SubProcess, UserTask, etc.) and which will indicate the concrete behavior of the current activity. For instance, here how this could be implemented in the bpmn diagram:
<callActivity id=“testId” name=“Call Activity” calledElement=“other-process-definition-id” flowable:inheritVariables=“true” behavior=“org.examples.behaviors.CustomBehavior”>
<multiInstanceLoopCharacteristics isSequential=“false” flowable:collection=“collection” flowable:elementVariable=“elementFromCollection” ></multiInstanceLoopCharacteristics>
- This behavior will be part of the hierarchy of the MultiInstanceActivityBehavior.
- It will be parsed by the BpmnParser and will be injected as an MultiInstanceActivityBehavior as part of the current Activity.
In this way, the goal is achieved without making any hacks and any changes to the Flowable Engine and moreover, the whole bpmn diagram will be easy-extensible.
Flowable experts, what do you think?
@addyhow : One option to model this is to have the synhronization in your subprocesses by using signal catch and throw events. The subprocesses that wait for the other element, have a signal catch in the beginning after an exclusive gateway that checks whether they must wait. The others throw at the end a signal throw to continue the others.
@enchobelezirev : There’s probably an easier way by overriding the org.flowable.engine.impl.bpmn.parser.factory.ActivityBehaviorFactory, specifically the #createParallelMultiInstanceBehavior and createSequentialMultiInstanceBehavior method. In your extended factory, you can return any subclass of the parallel or sequential behavior without having to change your model (this applies to any default behavior, btw).
@joram I also have a similar requirement but I am confused on the below points.
I have a model which will call a call activity in a parallel multi-instance and that call activity in turn call 3 more sub call activity (example Sub process A, B, C). sub process A have to run only once at a time but the other can run parallel .
If I have a collection of items (lets take an example of 10 items) then the sub process A of the item 2 have to be triggered once the sub process A of item 1 is completed.
I understand that this can be achieved by using signal catch and throw events.
which means there will be signal catching event in the beginning of the sub process and there will be a signal throwing event in the end of the process.
but in this case there will be 10 signal catching event running at the same time and how to throw a signal only to one of them
I’m not sure I follow the use case here, but reading you want to specifically correlate on certain data, it most likely means you can use the internal channel + events, and use event correlation to specifically wait for certain data values. With signals that’s harder to control, as they’re general pub/sub listeners.