Process variables revisions

Hey there,

My process engine shows a strange behaviour regarding process variables:

I have a process with execution listeners attached to sequence flows. In those execution listeners I’m in a while loop till a value of a process variable changes to true.

This process variable is set from another thread which somehow independent from camunda but which has access to to the process engine and its interfaces (like the runtime service). In this thread I set the process variable and if I query it afterwards the revision is updated each time:

[VariableInstanceEntity[id=11, revision=6, name=stepForward, processInstanceId=6, executionId=6, caseInstanceId=null, caseExecutionId=null, taskId=null, activityInstanceId=6, tenantId=null, longValue=1, doubleValue=null, textValue=null, textValue2=null, byteArrayValueId=null, configuration=null, isConcurrentLocal=false]]

My problem is that the Execution listener retrieves an old unchanged revision of the variable in its loop although he also queries the runtime service in the same way:

[[VariableInstanceEntity[id=11, revision=3, name=stepForward, processInstanceId=6, executionId=6, caseInstanceId=null, caseExecutionId=null, taskId=null, activityInstanceId=6, tenantId=null, longValue=0, doubleValue=null, textValue=null, textValue2=null, byteArrayValueId=null, configuration=null, isConcurrentLocal=false]]

Is this a bug, or is there some kind of workaround for this?

Best regards,
Hendrik

Hi Hendrik,

why do you wait in an execution listener until a variable value is changed?

Maybe it’s better to use an intermediate conditional event for the use case. It doesn’t block the thread and process engine resources (e.g. transaction to DB).

Best regards,
Philipp

Hi Philipp,

the problem is our use case. I know that it is probably not the normale usage of bpmn but for our requirements it would be nice to manually step through a plan (like some kind of debugging). My idea for that was to automatically attach the execution listener to each sequence flow in a deployed plan, then do a process migration and execute the plan afterwards in a step mode, where each sequence flow has to be confirmed.

I could also insert a conditional indermediate catch event for each sequence flow but then the plan would become unreadable because the diagram layout / drawing information is missing and though the plan could still be executed, one could not visualize it anymore.

Any other ideas how I could realize the “step mode”?

Best regrads and thanks for your answer,
Hendrik

Hi Hendrik,

I’m sorry but I don’t understand your use case completely.

Why do you need this “step mode”?
How is this related to process instance migration?
Do you want to run the process instance always in this “step mode” or only once?

Maybe asynchronous continuation is an option for you.

Best regards,
Philipp

Hi Philipp,

We use BPMN to operate some industrial manufacturing systems with a variety of components. Sometimes it is useful to debug a process step by step. Therefore my idea would be to take the original process, read its BPMN plan, modify it by attaching the execution listeners to each sequence flow and then migrate the original process to the modified one. This migration might be reversed for normal production but it might also be repeated if things in the production change and parameters of the process have to be modified.

As already mentioned, I know this is maybe not the normal usage of BPMN but as far as I understand the camunda framework should allow those things and I still don’t understand why I get different revisions of the process variable from the runtime service.

Thanks again for your efforts,
best regards,
Hendrik

Hi Hendrik,

you can not get the updated variable value in the event listener because of the transaction boundaries. You get always the same execution with the same variables. One workaround could be to get the variable by another transaction or thread. For example:

ProcessEngineConfigurationImpl configuration = // 

String variableValue = configuration.getCommandExecutorTxRequiresNew().execute(new Command<String>() {

   public String execute(CommandContext commandContext)
   {
        return (String) runtimeService.getVariable(executionId, "VAR");
   }
});

But this is not a really good way because you block the current thread and transaction which may lead to various problems.

Another way could be to play with the job executor and mark each activity as async. In debug mode, you execute the jobs manually. Otherwise, the jobs are executed by the job executor. Note that this may require a deeper understanding of the job executor.

Does this help you?

Best regards,
Philipp

1 Like

Hey Philipp,

sorry for the late response but thanks a lot for your answer. I used another way where I have a Singleton Manager Class now which controls the “Step Mode” with the execution listeners on the sequence flow.

I think you are right and the best way to implement it in a clean way would be to extend the job executor for this, but for now I’m fine with my “dirty” solution.

Thanks a lot for your effort, I really appreciate it!

Best regards, Hendrik