Suspend Process Instance in JavaDelegate

Dear Community,

I am trying to suspend a process instance in one of its service tasks. I did it like described in Camunda synchronous process instance wont suspend - Stack Overflow

However, doing it like that I get an optimistic locking exception. Apparently, when I suspend the process instance at the same time the process engine finishes the Java Delegate and wants to write that to the DB as well.

So, as a workaround I included a Thread#sleep for testing purposes. Now the process engine behaves funny. The Java Delegate repeats getting executed. Why is that?

The code of my JavaDelegate

@Service
public class SuspensionDelegate implements JavaDelegate {

	@Override
	public void execute(DelegateExecution execution) throws Exception {

		RuntimeService runtimeService = execution.getProcessEngineServices().getRuntimeService();

		String pid = execution.getProcessInstanceId();

		VariableMap variables = Variables//
				.createVariables()//
				.putValue("processInstanceToSuspend", pid);
		runtimeService.startProcessInstanceByKey("Process_Suspension", variables);

		System.out.println("Suspending Process Instance ...");

		runtimeService//
				.updateProcessInstanceSuspensionState()//
				.byProcessInstanceId(pid)//
				.suspend();

		Thread.sleep(5000);
	}
}

Any hint is appreciated.

Hi @philipp.hehnle,

Each JavaDelegateis executed by a job executor. A job that gets stuck, may prevent the completion of the process. Therefore, a timeout is implemented. This timeout is configurable via the property camunda.bpm.job-execution.lock-time-in-millis the default is 300000. Can it be, that the lock time is too restrictive?

I did not change this property. So, it should still be the default value.

Hi @philipp.hehnle,

Is your delegate called by a service task?
I assume that the following is happening:

  1. Your delegate is called
  2. You suspend the process
  3. You add the Thread sleep
  4. Your delegate completes BUT fails because its process instance has been suspended and completing a task would advance the token, which is an invalid operation for suspended processes. Since the delegate failed, the service task will be repeated.

You can try using a TaskListener or an ExecutionListener.

1 Like

Hi @StephanHaarmann,

I tried the same setup with an execution listener. I get the same result.

Your assumption seems plausible. Can you think of a way to get it working?

Hi @philipp.hehnle,

Below is a great simple example created by @Niall

Notice: “Suspend this instance” service task is synchronously executed.

2 Likes

@hassang Thank you for sharing the example.

However, I am not entirely getting the point of the thread. Niall states that you need to set async continuations in the process model. At those points the suspension can become effective.https://forum.camunda.io/t/suspending-a-process-instance-unconditionally/15325/16?u=philipp.hehnle

He does not say anything about the event subprocess. So, as far as I understand the fact that the suspension is triggered in an event subprocess should not have any influence. Am I right or am I missing something?

I set an async continuation before at the subsequent activity. However, the SuspensionDelegate keeps repeating itself.

You could “Message Throw” to a different process, with a message containing your process id.
This other process starts on “Message Receive” and suspends the process with the ID in the message.

Only make sure that you don’t set it for the SuspensionDelegate service task.

I believe using an event sub-process is required for the solution to work. Otherwise, suspension implementation will get in an infinite loop.

1 Like