I have an interrupting timer boundary event on a service task but it does not trigger the alternate path.
I don’t understand where the problem is and hope someone can help me
If I use a user task instead of a service task it works. That means: If I don’t do anything in the cockpit the timer interrupts after one minute and the alternate path is going on. So I think the problem is my service task (I have also tried to set camunda:asyncBefore=“true” on the service task).
I want to have a lot of cases (over 100) in a short time. So I don’t want to click in the cockpit for every case. Therefore I try this with a service task and don’t want to use the user task.
I have an IntelliJ project as a spring boot application.
The code of the service task with the boundary event looks like this:
package de.uniulm.process;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import java.util.concurrent.TimeUnit;
public class VersAusstellenDelegater implements JavaDelegate {
private int min = 600;
private int max = 1800;
@Override
public void execute(DelegateExecution delegateExecution) throws Exception {
System.out.println("*** Versicherungsschein ausstellen ***");
int random = (int)(max * Math.random() + min);
System.out.println("--- random = " + random);
TimeUnit.MINUTES.sleep(2);
System.out.println("Time has expired");
}
}
I can see in the log and in the camunda cockpit that the process waits two minutes. After two minutes there comes the output and the process goes on. But the timer does not interrupt after one minute.
So this is actually by design, I’ll try to explain whats happening and then try to work out what exactly you need to do and then hopefully find a solution for you.
There are some fundamentals about the engine which need to be remembered when trying to understand how certain interactions like this take place.
A single process instance should never have more than one thread working on it at any one time. (to ensure the state does not get corrupted)
The process engine will never interrupt a running thread - it will always let the tread finish before assessing the state of the process.
So what’s happening here is that
The tread reaching the service task and commits to the database the timer event.
The tread then runs the java class - which exceeds the timer
a. The timer is only checked when the tread comes to a wait state so it’s not triggered.
The thread finishes running the code and moves on to the gateway.
a. As soon as the Thread leaves the service task the timer is now out of scope and so will never trigger.
This is why it works on a user task - because with a user task there is not active thread on the process instance and so the timer can easily interrupt the task.
So this brings me to the next question - what exactly is the end goal you’re trying to reach?
Are you trying to set the limit on the time a service task will run?
Hi @Niall
Thank you for the explanation. This helped me a lot in understanding what’s going on behind the scenes.
As far as I understood I would have to create an independent subprocess to foster an external event.
I found a workaround for my case by using a conditional boundary event.
I’m going through a similar problem, and I’m trying to make it work with a conditional boundary event as well. I’m using a conditional boundary event, and I’m targeting the “update” of a specific variable within my process.
Can you please share your piece of code related to the service task with the conditional boundary event attached to it, like you did in here?
However, of course, I’d like to show you how I solved this.
I set the variable in a service task (doesn’t have to be the service task the conditional boundary event is attached to, the main thing is that it’s bevor you need it) as follows:
package de.uniulm.process;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import java.util.concurrent.TimeUnit;
public class MyDelegater implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) throws Exception {
int randomPrio = (int) (Math.random()*(10-1)) + 1;
if(randomPrio % 4 == 0) {
delegateExecution.setVariable("prio", "1"); // = true, go other path
} else {
delegateExecution.setVariable("prio", "0"); // use path of service task
}
}
}
In the properties of the conditional boundary event in the Camunda Modeler, I selected “Expression” as condition type and set #{prio == '1'} as the expression.
I’m facing the same issue. I have a subprocess with 2 parallel running service tasks. I have a timer boundary event on the sub process. I would like a timer of 5 secs for them to run. In case either doesn’t finish in 5 secs, timer should kick in and move to the timeout task.
However, the timer doesn’t seems to work.
Any ideas what am I missing here?