Hello my friend!
Here are the answers:
Always keep in mind that everything you see in the cockpit is nothing more than a representation of what is saved in the Camunda database, so you will only “see an instance token in a box if it has been saved in the database”.
We have 3 types of “save points” in the Camunda database, namely Async Before
, Async After
and stop points (user tasks, timers, etc.)
You can understand more about this in the official documentation below:
Instance suspension suspends any activity that may change the state of the instance token, that is, that makes your instance move within the cockpit.
Knowing this, imagine the following scenario:
Imagine that you have a user task (which is a transaction point), when the instance reaches this user task, the current state will be saved in the database. So you have a kind of checkpoint there (like in video games), and if anything goes wrong, you will return to this checkpoint.
After this user task, you have a service task that is a Java Delegate… and a service task only saves the state in the database before (async before) or after (async after) being executed, if it has been marked as Asynchronous Continuation, and if it has not been marked, it will not save the instance state in Camunda.
So we can see 2 situations… the first is that, if you did not set your service task as async continuation, your save point was the user task… that is, if you suspend an instance while it is executing an internal method of your delegate, the execution will stop at the same time, and your instance will be at the “last save point”, which in this case was your user task.
The second situation is that, when you activate the suspended instance again, it will execute from the last moment it was saved, which in this case was the user task, before you completed the task (as I mentioned above, the suspension affects any activity that can change the token state… and the “COMPLETE” of the user task is what makes the instance token move).
In short, I mean that, by suspending the instance in the middle of executing a delegate, it will stop executing at the same time, and your instance will return from the last save point, and thus will execute all the methods contained within your delegate again when you activate the instance again.
Example:
-
Within your delegate there were 2 methods… a saveDataOnDatabase() method and a showSavedDataOnConsole() method.
-
When executing the saveDataOnDatabase() method, you suspended the instance, therefore executing the saveDataOnDatabase() method but did not execute the showSavedDataOnConsole() method.
-
Your instance returns to the user task until you unsuspend it and complete the user task.
-
When you do this, your instance will execute the saveDataOnDatabase() method again and then the showSavedDataOnConsole() method.
Therefore, a good practice is idempotence in your methods and APIs / Microservices.
1 - When you suspend an instance, Camunda saves the state of the instance informing that it is “suspended”, and that it should stop its execution and resume from the last point at which it was saved, in this case a breakpoint or async before / after.
2 - When suspending a process instance, Camunda does not complete the current activity. Suspension interrupts execution at the same time, even if an activity is in progress. Therefore, the activity executing at the time of suspension will not be completed until the process instance is resumed and this will cause the entire activity to be executed again.
3 - Yes, when you suspend a process instance, Camunda stops the execution of the current activity immediately. There is no waiting for the current activity to be completed. The process is suspended in the state it is in, without completing the activity that is currently running.
4 - Camunda does not revert everything that was done externally… but rather what was persisted in Camunda. In the example I explained at the beginning, if the service task saved something in an external database, Camunda cannot revert what has already been done… therefore this will be executed, but your Camunda instance will return to the last saved state, requiring you to execute the service task again from the beginning when you resume the activity of the instance.
If you want to do a quick test to test this scenario, create a workflow, and place a service task with a delegate, containing the following code:
package br.com.gerandocodigo.camunda.delegates;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.springframework.stereotype.Component;
@Component
public class TestDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) throws Exception {
System.out.println("HAS STARTED MY PROCESS INSTANCE");
execution.setVariable("startVariable", "Created at begin.");
Thread.sleep(60000);
execution.setVariable("finishVariable", "Created at end.");
System.out.println("HAS FINISHED MY PROCESS INSTANCE");
}
}
With this you will be able to understand exactly the behavior, checking what will be created in the terminal after the task is started and suspended. You will see in the terminal the “HAS STARTED MY PROCESS INSTANCE”, but you will not see the message “HAS FINISHED MY PROCESS INSTANCE” nor the process variables, because the variables are only “shown” in the cockpit when Camunda saves the current state.
I hope this helps, and if my answer has answered your questions, please mark my answer as “Solution” so that other members of the community can easily find the answer they are looking for if they have the same question.
William Robert Alves