Double emit of start and end-event in spring eventing bridge


#1

Hi all,

I am conducting a small test scenario where I apply a spring component with @EventListener annotations to handle the events that are emitted by the process engine. This way I might have a more generic way to react to those events as opposed to declaring execution listeners in the modeler per activity.

What I notice is that the event listener is invoked twice for the start event of a process; for the end event of a process; and for timer events for both the start and end-events. The values of the DelegationExecution seem to be equal for both invocations. For other activities the start and end events are only invoked once.

Can someone explain why this method is invoked twice for those events? Or could there be some issue in my code setup? I am using a simple spring boot application with embedded process engine and a simple process definition; consisting only of a start event; a script activity that just prints a line to stdout; and and an end event.

Thanks in advance for your responses.

Kind regards,
Patrick


#2
Hi @Patrick,

for every BPMN-Flowelement the workflow engine throws a start and an end event. Therefore you receive two events when processing one flow element. You need to check the type of the event before execute your logic if you want to avoid double executions.

@Component
public class CustomHistoryEventHandler {

private static final Logger log = LoggerFactory.getLogger(CustomHistoryEventHandler.class);

    @EventListener
    public void handleEvent(HistoryEvent historyEvent) {

	log.info(">>>>>>>> received HistoryEvent: " + historyEvent.getId());
	log.info(">>>>>>>>            instanceOf: " + historyEvent.getClass().getName());
	log.info(">>>>>>>>             eventType: " + historyEvent.getEventType() + "\n");
    }
}

#3

Hi @McAlm,
Thanks for your response.

I understand that upon a transition both a start and an end event are fired. However, in my case with method signature:

@EventListener
public void notify(final DelegateExecution delegateExecution) {
...
}

I receive some notifications twice.
For a start event I get callbacks for start twice. And for the end event I get callbacks for end twice.

To illustrate I share with you my logging output for the tested process; that comprises a start event -> a script task that does nothing -> end event.

> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: Start of the process(StartEvent_1) - Event name: start 
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: Start of the process(StartEvent_1) - Event name: start 
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: Start of the process(StartEvent_1) - Event name: end 
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: Start of the process(StartEvent_1) - Event name: take 
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: First step(Task_16ksokd) - Event name: start 
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: First step(Task_16ksokd) - Event name: end 
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: First step(Task_16ksokd) - Event name: take 
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: End of the process(EndEvent_0gil19k) - Event name: start 
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: End of the process(EndEvent_0gil19k) - Event name: end 
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: End of the process(EndEvent_0gil19k) - Event name: end

The process is started by executing runtimeService.startProcessInstanceByKey("…");

For the duplicate entries, the values provided as DelegateExecution are equal; according to the equals method on DelegateExecution.

As you see, the Task behaves as I expect. The start and end process emit duplicate notifications. The same is true for timer events. Those are duplicated as well.

So I understand your answer, but the behavior I encounter is a bit different. I’d expect a start and an end notification (as you described), but I encounter start; then start again and then end. And finally a take transition.

Hope you can help me a bit further with these clarifications.

Regards,
Patrick


#4

Have you bind your EventHandler to the BPMN model as well?


#5

Not sure how to do that exactly.

I use the autoconfig mode of spring-boot. The relevant part of my configuration is this:

camunda:
    bpm:
       application:
            scan-for-process-definitions: true
       auto-deployment-enabled: true

Furthermore, the class that contains the eventlistener method has a @Component annotation and the bpmn files are in the resources folder of the module that contains the main class for the spring boot packaging plugin. (I use maven.)
Given this setup, everything is loaded and deployed automatically and I do not use a specific binding configuration.

Can you give me some pointers how to implement this binding?


#6

My question was with regard to the BPMN file itself: Does it bind the Handler classes to the events or do you use the @EventListener annotation only?
In the modeler you can define those event handlers on specific flow elements, but of course you should use only one approach…


#7

No I do not use that in this setup. The Listener tab in the modeler is empty for all three elements.

It is the way I started off, but the spring approach seems to be more generic and thereby easier to maintain.


#8

Hi @Patrick,

I was able to reproduce. Currently for start and end events the according Spring Events are obviously generated twice. Truth is, the first start event belongs to the process itself and the last end event as well.

I think you can use the activity instance id to distinguish between these two start respectively end events:
In the case of the process instance event, execution.getActivityInstanceId ().equals(execution.getProcessInstanceId()) should hold. When the start event is executed, the start event has its own activity instance id.