Share the Jobs between two Engines via Asynchronous Continuations

Hello to all camunda experts!

I would like to share my case with some issues with Asynchronous Continuations

In my scenario, I want to share a model between two engine.

I have first engine-instance called it backend-engine and I have the second engine-instance called domain-engine running on the same DB.

I have model with some user-, service-tasks and intrermediate events.

Each element has its own delegates.

I deploy the model via domain-engine and the user and service-task delegetes are also deployed on domain-engine.

The backend engine has delegetes only for intrermediate events.

I would like now to run all the delegetes on both engines.

For this I have enabled the asynchronous continuations in the model, but it seems to work only with usertasks.

The model in first case only with usertasks is work as expected:

First run a delegate on domain-engine, then the listener on backend and then delegate again on domain-engine

As next step I added one service task and it seems that the service task does not close the second transaction, so I get ClassNotFoundException on domain engine.

How can I define, that the second transaction should be fired throws job executor on backend engine?

Cheers,
Alex

Can you upload the model itself?

Hi @Sokolov,

you have to configure the job executor to be deploymentaware. Have a look at the docs: https://docs.camunda.org/manual/7.11/user-guide/process-engine/the-job-executor/#job-execution-in-heterogeneous-clusters.

Hope this helps, Ingo

1 Like

Hi @Ingo_Richtsmeier ,
thanks for reply.

Sure, I setted DeploymentAware as true:

hier is my complete config, the same on both engines:

camunda.bpm:
webapp:
index-redirect-enabled: true
job-execution.deployment-aware: true
job-execution.enabled: true

Cheers,
Alex

HI @Niall,

sure, hier are the models.

test-domain-v1.bpmn (4.6 KB)

test-domain-v2.bpmn (5.6 KB)

Cheers,
Alex

Try adding an async after on the service task, that will force a commit before the listener runs.

added an async after service task, but nothing changed. The ClassNotFound exception occurs again.

actually, according to camunda documentation, the transaction boundaries should be set on timer

I added also a timer after service task, but the same exception occurs.

In the example with timer, it gets a new entry in the table “act_ru_job”.
But the job is then performed by wrong engine.

I expect the job to be done by backend-engine, but it’s always run by the domain-engine.

If I try to increment number of timer retry, I get the same exception, because the delegete is on other engine located.

The question is: how Camunda decides which job will be executed by which job executer ?

Hi @Sokolov,

after checking your process models I assume that you want the listener code to be executed only in your backend process engine. Is this correct?

If yes, this is not possible with your process models. You have to either distribute the listener code to both engines or use a call activity to pass the flow to a separated process, executing only the intermediate throw event with the listener on the backend engine.

Hope this helps, Ingo

1 Like

Hi @Ingo_Richtsmeier,

thanks for reply.

I’m trying to set the transaction boundaries of asynchronous continuations correctly.

Opening a transaction is works propertly.

Now the problem is to close the opened TA.

Clousing of an TA works by an userTask, as you can see in first model (test-domain-v1.bpmn).
First the Listner on Domain Engine → Listner on Backend → Listner on Domain → and so on…
I’dd like the same behavior in second model.

This corresponds to the documentation about (wait-states).

A usertask closes a TA because it has a waiting state, but in the documentation there are other waiting-elements such “Receive Task”, “Timer Event”…
I expect that these elements will close a TA also, but it seems to not working.

I can close an TA only by usertask, speak userTask => end of TA, so I can close TA, but it is not comfortable, my idea to use other waiting elements to manage the transaction boundaries.

Distributing the code between engines, in my scenario, is not a good idea, listener code of throw events should only be managed by administrators on backend, the other domains is for developers without admin privileges.

Throw event listener are connected via reactor extention on backend, so that domain does not know about Throw event listener.

" I assume that you want the listener code to be executed only in your backend process engine. Is this correct?" - No, it is not correct, as I explaned in my answer, it should be like “zig zag execution” between backend and domain job execuror.

Thanks again,
Alex

Hi @Sokolov
did you try to use camunda:asyncAfter=“true” in “User Task 1”?

Michal


Now I see you have async in “Service Task 1” … so camunda:asyncAfter=“true” in “User Task 1” doesn’t help probably.

But … what about to set camunda:asyncAfter=“true” in “Service Task 1”?

HI @Michal_Moravek,

amunda:asyncAfter=“true” in “Service Task 1” doesn’t help too.

Alex