PROCESS_CANCELLED event when "Terminate End Event" reached and 'terminate all' is false

Hi,

this question is related to this Thread : http://forum.flowable.org/t/why-is-process-cancelled-event-sent-from-a-terminate-end-event-instead-of-process-completed/87

It is not fully clear to me, but contextually I seem to make up that in that thread, Robert describes a usecase where a “Terminate End Event” is used with the property 'Terminate All" is true.

However, we have the following behavior when the property “Terminate All” is set to false
(sorry, still on activiti 5.21…) :
Scenario:

  • a process contains a subprocess
  • the subprocess contains a Terminate End Event with “Terminate All” property is false.
    At runtime, the process should reach this Terminate End Event
    Result:
    The subprocess scope is correctly terminated , and the main process continues (OK).
    BUT: an activit event “PROCESS_CANCELLED” is thrown (with reference to the main process instance id).

We have a listener that is triggered by the “PROCESS_CANCELLED” event, so now or downstream code incorrectly marks the main process as “cancelled” , although it actually still is running.
We haven’t found a way yet to filter out this “process_cancelled” event.

In my opinion, this process_cancelled event should not be thrown when ‘terminate all’ is false.
Compare it to a “Message boundary Event” on a subprocess, with property ‘cancel activity’ set true : this doesn’t throw a process_cancelled event either.
Or, the event should rather be name “subprocess_cancelled” (?)

Screenshot of the process (I can’t upload xml, unfortunately):

Question:

  1. would you agree that this is a bug / wrong behavior ?
  2. Any ideas for a quick workaround that we could apply in our listener (how could we distinguish that this “process_cancelled” event should be filtered?

thanks,
Pieter

Yes, that’s wrong behavior. What you could do is check via the RuntimeService if the process instance is still running. It’s not great, but I don’t see many other alternatives.

Best regards,

Tijs

Unfortunately, that approach also doesn’t seem to work. The event is dispatched before stopping either the current scoped execution or terminating the process instance (in case the end event is a terminate all event). Thus, checking it in the runtimeService doesn’t help us.

//terminateProcessInstanceExecution method
sendCancelledEvent( execution, terminateEndEventActivity, processInstanceExecution);
deleteProcessInstance((ExecutionEntity) processInstanceExecution, execution, ...);

It also seems that the dispatching of the event was already present from the second implementation of the behaviour in the engine, which can be viewed here: https://github.com/flowable/flowable-engine/commit/33f893be8c7ffb8a437c529b68f6c7d8925758fc
Thus even before the terminateAll flag was introduced, a terminate event always triggered a process cancelled event.

I don’t know what the impact is when we just remove the line that emits the event when just the current scoped execution is stopped?

Ok clear.
Regardless of the fix, we will apply a workaround by using slightly different BPMN symbols:
So, we’ll not use terminate end event in a subprocess
but, instead:
use a “end error event” in the subprocess ; and add a boundary error event on the subprocess (obviously both using the same error reference)

That should achieve the same functional effect.

Another approach to try is walking up the (parent) execution hierarchy to the first execution that has a scope value of true. Based on the execution that has a scope I believe you should be able to determine whether or not the event is related to a process instance or a subprocess instance.

ExecutionEntity execution = Context.getCommandContext().getExecutionEntityManager().findById(event.getExecutionId());
while (!execution.isScope()) {
execution = execution.getParent();
}

if(execution.getParentId() == null) {
// Process Canceled
} else {
// SubProcess Canceled
}

Also if you are using call activities you may need to check the super execution value depending on whether you consider a process started by a call activity as a “subprocess” or not.

The code example above is based on Flowable 6. But I think it should apply to Activiti 5 as well.