Problem with synchronous startProcessInstanceByKey

Hi, I’m trying to migrate from Flowable to Camunda and one specific issue is blocking my progress for now. I have the following code:

private final Map<String, List<SomeClass>> processListeners = new HashMap<>();

// in the constructor:
CamundaReactor.eventBus().register((ExecutionListener) execution -> {
	triggerEvent(execution);
});

private void triggerEvent(DelegateExecution execution) {
	List<SomeClass> listeners;
	synchronized (processListeners) {
		listeners = processListeners.get(execution.getProcessInstanceId());
	}
	if (listeners != null) {
		// this never happens
	}
}

public ProcessInstance startProcess(String processDefinitionKey, Subject subject,
		SomeClass... listeners) {

	synchronized (processListeners) {
		ProcessInstance processInstance =
			processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey);

		if (listeners.length > 0) {
			processListeners.put(processInstance.getProcessInstanceId(), Arrays.asList(listeners));
		}

		return processInstance;
	}
}

The problem is that when I call “startProcess” and pass some listeners, they are not called because “startProcessInstanceByKey” is synchronous and the “triggerEvent” method is called BEFORE “startProcessInstanceByKey” finishes (and hence the listeners are added in “processListeners”). Then, in “triggerEvent” I read an empty “processListeners”.

I’m actually not sure how do I fix that at all. Marking the start event of the process async does not work for me as these could be user-generated definitions and I cannot expect users to always mark them as async.

Any ideas would be appreciated! Thanks!

Hi @boris,

usually, you would register the listeners in the process statically or use a BpmnParseListener to register the listener while deploying.

Why do you try to register the listeners dynamically in this way?
Please describe your use case in more detail.

Best regards,
Philipp

Hi, thanks for the answer.

Well, I’m trying to write something generic that would allow for example plugins to be written for the system that I develop and they would use a nice API - for example deploy a new diagram and then start processes from it and attach listeners. Also, they can start processes of other diagrams that they have not written themselves and be able to attach listeners for those processes too. I think that is a pretty normal use case. Or am I missing something?

As I said, I’m migrating from Flowable to Camunda (actually already did) and this is the only thing that is a major difference between the two that cannot be done in a clean way in Camunda at all (as Flowable/Activiti seem to trigger those events asynchronously). The way I circumvented this was to put a variable in each process with a generated UUID and then use that to figure out which listeners are attached to it. Any ideas for some better way?

Hi @boris,

your way with the UUID variable sounds good for this use case.

Best regards,
Philipp