I have the camunda process as below. Each service task has async-before and Exclusive options enabled.
The first service task calls a Java delegate which makes a SOAP call and has a very big response and saves the response to the database.
The Java application listens to MQ events and triggers the camunda process. Sometimes we get few messages at the same time (with millisecond difference). Then I see that each MQ event triggers a camunda process instance which runs the same delegate and this cause heap exhaustion issue and crashes the application.
So inside the Java delegate I want to somehow make sure that other camunda process instances are not running the same delegate at the same time. Is that possible?
I only want this for 1 or 2 Java delegates which deal with large objects. For other Java delegates it is fine if multiple camunda process instances run the delegate at the same time
Could you consider redesigning this from a java delegate model to an external service worker model?
That way the external service worker becomes responsible for determining how many tasks it can take on , and it the number of tasks for the worker starts getting large, you can spin up extra workers.
In the doc I posted before, there’s Java API which includes some code examples.
Topic Name is how multiple external service workers know who’s work is whose. You could call the topic something like “BigRESTQuery”. To limit the worker to one at at time, you would write something like:
List<LockedExternalTask> tasks = externalTaskService.fetchAndLock(1, "BigQueryWorker")
.topic("BigRESTQuery", 60L * 1000L)
How do I subscribe to the topic and complete the task in the “tasks” variable. I am planning to create an simple externalTask.java which is triggered when a camunda process comes to the service task. In externalTask.java I will get the waiting task for my topic and complete it and wait for a second so that the concurrency can be broken.
Should I create a method inside my ExternalTask.java class? How/who will call the method in that case so that the task can be completed?
And in “externalTaskService.complete()” what can I give for variables? I am planning to just create an empty service worker(in the same app where camunda is running) which just completes a task and wait for a second and complete another and so on so that the concurrency can be broken.
My understanding is that you run it in a different program (though there’s nothing saying you can’t run it in a distinct thread).
You write it like a while-true loop…
It looks for tasks to be done (fetch tasks on topic BigRESTQuery), locks the first one, does the work, sends the work to Camunda, then loops.
If there’s nothing to be done, it sleeps for a bit, then loops.
You’ll want to code a Java program that does something like:
Can I have external task worker (which completes the task) in the same Spring Boot application or should it be in a different application.
I intend to use it in same app and also use Camunda Java API and not REST API so guessing that I don’t need to configure camunda base-url etc details.