I’m stuck with my process. Below I present a part of the whole process, but my issue is presented in this diagram.
Behind the parallel gateway I have one Service Task and one User Task. In the service task has been configured retry mechanism R10/PT1M. And the service task does an integration over SOAP. The service task is Asynchronous before and exclusive. I can’t set exclusive=false, because of OptimisticLockingException. And this requires additional mechanism checkig if the integration has been completed (Camunda retries the task when OptimmisticLockingException occured)
In a case, when the Service Task fails, the retry mechanism blocks the process for a 1 minute. If in this time I call the method
void complete(String taskId, Map<String, Object> variables); from TaskService,
the user task will start with a long delay, e.g. about a minute.
Unfortunately, I need it without any delays because the user task is the part responsible for communication with the user in the browser.
I will be grateful for any hints on how to solve it.
Have you set the user task to async before? I have setup your model and I have no problem completing the user task whilst the service task is blocked…
@Webcyberrob yes, I have. Both user task and the service one are async before and exclusive=true.
for a user task it really shouldn’t make any difference…Anyway, the only other crazy thought I have is are you resource constrained? eg are you running in a test env or similar which only has one thread, or one connection in a connection pool etc?
@Webcyberrob should Camunda use only one thread in this case? Both of the tasks have exclusive=true. So, why more than one thread is needed here?
for the service task, given its asynchronous, it will be run by a job executor thread. Hence one job executor thread will be blocked on the service task except when its paused between retries.
When you complete the user task, this will occur in a client thread. However, if there was only one db connection, and it was consumed by the service task, then I could see the user task thread blocked waiting for a DB connection so it can flush state to the DB…
Thank you @Webcyberrob for your support.
I’m confused, you said:
When you complete the user task, this will occur in a client thread.
So, why do we have to set exclusive=true if we want be protected against OptimisticLockingException? What does this param do ? If the user task is completed in anoher thread (the client one) ?
I thought, the whole process is performed in a one thread, expect jobs set to exclusive=false.
@mariusz in your first diagram, are you having the parallel activity occurring because you want the user to work on the user task even if the Service task is not complete yet?
Assuming the above is a “yes”,
then could you just have the service task set a process variable such as “servTask = True” when its complete, and when the User Task is attempted to be completed, the user task looks for to see if the variable == true, if it does not then it throws a error, preventing the user task from being completed.
Also based on your explanation wtih Rob, yes it sounds like your env does not have enough workers/executors. If it takes a whole minute for the user task to appear, then your camunda env seems to be taking a while to setup.
Can you recreate the same setup using the Default Camunda Docker container and see if you get the same result: https://github.com/camunda/docker-camunda-bpm-platform
the exclusive flag is for the job executor. When set, the job executor will only run one execution path from the process instance at a time. The exclusive flag on a user task probably only has meaning when the async after flag is also set. The user task execution its-self is running in the context of a user and thus its a ‘client thread’ which actually performs the user task. Note: async before on a user task is redundant because a user task is by its nature async before with respect to engine execution semantics.
To explain the thread architecture a little more, in an application server context (eg Tomcat, Wildfly etc), there are two thread pools. One is owned by the job executor and will execute asyncronous executions. The client thread pool is used to handle requests received by the application server either via user interactions or system to system interactions via say the REST API. Hence the execution of the user task will typically occur in a client thread.
Note that both these thread pools may use a common database connection pool. Hence if you only had one DB connection, then it could expose resource contention and block one of these threads. Thus I think there is something in your environment causing the behaviour you observe…