What are local variables?

Hello,
I’m trying to understand what local variables are.
My initial idea was that:

  • the process instance is represented by a token which is moved through the process
  • if the process has some forks, like parallel gateways, we get multiple tokens (corresponding to multiple executions)
  • process instance variable is a global one, equally accessible to all tokens (executions)
  • local variable is accessible only to a single execution (token)

But while developing some code, I see my understanding is not quite right. It seems, executions (and local vars) are somehow related to individual activities or subprocesses.

My questions are:

  • is it correct to assume that multiple paths though the process are multiple executions (===tokens)?
  • how do I assign different data (variables) to different paths (executions? tokens?)? Local vars? Something else?

Thanks
Andrius

1 Like

The docs go deep into the variables system
Process Variables | docs.camunda.org

Local variables are exactly like process variables except their scope / lifecycle is restricted to the duration of the activity they were created in.

Process variables will be available to all tokens / forks in that process instance.

2 Likes

(Bold is mine)

This is not quite correct IMO. It’s restricted to the duration of the var. scope which may be more than the activity – as the docs you linked explains. One just has to put the value into the right scope.

@fml2 can you give a example of local var scope that exists a beyond the life cycle of a single activity? (Activity = anything that generates a Runtime/Historic Activity Instance)

The smaller nuance may be multi-instance scopes which can be within the activity scope within is within the process scope: but even then the multi instance still is restricted to the parent activity scope.

They are not very useful then. If an activity is implemented as Java delegate - it has its local java vars. The local vars will not survive past that activity anyway. The only case I find it useful - as a temporary storage on some gateway - waiting until next activity picks them.

I need to attach some data to a single token on its whole path. I need some process instance data and some token specific data. How do I implement it in Camunda?

If it’s not doable - the the idea of having multiple tokens (executions?) is not very useful, too :frowning:

Is it possible to get identifier of a “token” or its “path” in Camunda?
So that I can use it to organize storage for it outside camunda, or just as process variable bound to that ID?

Hi @andrius
Why exactly do you need this?
Does creating a regular variable cause any kind of problems?

I’m trying to model a process dealing with hierarchical data.

The customer should be notified about events (past or upcoming). We should be able to prepare and deliver several messages about one event: first we start with a single initial message, but eventually, more messages can be added, like follow-ups and conclusion messages. Every message has its own workflow - it can be updated, scheduled for delivery, in delivery, delivered. The workflow of event is tied to the state of its messages: for example it is closed when all its messages are delivered and event end time has passed without anyone adding new messages.

So, my main entity is Event. It has own data attributes like customers, summary, start and end times. This data is common to all this events’ messages. So I model a single Event as a process instance. But individual messages have their own, independent and possibly different paths though the delivery workflow. So, I thought it is natural to have them as “executions” or “tokens”.

Well, there are multiple messages for one event. I could create a multivalued or list variable to store them. The problem is - when a workflow token of a message reaches some Activity - how do I know -which message was that? It may be multiple messages at the same Activity - how do I know - which one just arrived and should be dealt with?

I also tried to store them as local vars. The problem is - local vars are scoped to the current activity, whatever that means. They will not survive though the whole path of the token.

I cannot find a way to get the data that travels with that token. A regular variable just has the common data for all tokens of current process instance - nothing specific to the token at hand.

I also thought about using multiinstance subprocesses. They should deal nicely with local vars (not sure if they are local, but, as I understand, each subprocess instance gets its own). The problem is that in our case we do not have all the messages at once. A new message may be created at any time. So, we never have a final iterable list of messages, which, as I understand, is required to create a multiinstance subprocess.

Thanks for the detailed reply, It’s a little hard to fully inderstand the situation, would you might posting a model of what you’re doing so i have a better idea?

Here it is:
notification.bpmn (41.1 KB)


Notification === Event
Here, “Add new message” and “Reschedule” events fork a new execution. I would like to attach message data to it so that everyplace the execution is seen, I can also have the message data. But my tests reveal that just after I create a new process using “Create draft notification” with local variable messageId, I can no longer correlate the execution using
runtimeService.createMessageCorrelation("Message_update_draft") .processInstanceBusinessKey(businessKey) .localVariablesEqual(localVariablesQuery)
where localVariablesQuery includes that messageId.

I have not done this myself yet, but if I understand the docs correctly, the scope hierarchy is like this: Process instance – process branch (execution) – single activity. If you use setVariable you usually work with the process instance scope – which is too large. If you use setVariableLocal within a java delegate you get the activity, which is too small. The goal is to get the middle thing, the execution, and use setVariableLocal on that. I’m not sure how to to this. There are getParent and setVariable with a parameter for the activity. I’d try that.

@andrius Local Vars are sometimes useful even within an activity. We use them to call a subprocess and not pollute the caller process’ data.

I just stumbled over this thread because we have a problem which we think could be solved by “token-scoped-variables”. Since there is no such thing. Is there a way to access the id-value of the current token?

I guess I can answer the question by myself now:

To my current understanding execution.getId() is the identifier for the current token/path of execution.

If variables should be scoped to the current execution context that has to be done with setVariable(s)Local(...)
e.g.
execution.setVariableLocal(key, value)
or
runtimeService.setVariablesLocal(...)

Please correct me if this understanding is wrong.

1 Like

why we need to persist local variable in db when it is not accessible anywhere?
is there any option to skip saving these local variables in db?

it could be better when we could access to local variable before see wait states

Hello my friend @Amir_Roshan!

Local Variables are saved in the process instance database… This happens because local variables are associated with a specific instance of the process and need to be stored so that they can be retrieved and used later during the execution of the process.

Local variables are different from global variables, which are shared among all process instances. Local variables are specific to a single process instance and are useful when you need to store temporary or instance-specific data. They are stored in the database to ensure data persistence throughout the lifecycle of the process instance.

After the process instance is terminated in Camunda, the local variables associated with that instance are also removed from the database. This occurs as part of the process of automatically cleaning up resources associated with the completed process instance.

Therefore, local variables do not persist after the process instance completes. They are automatically removed to free up resources and maintain database integrity, as these variables are no longer useful after the instance ends.

Therefore, it is important to remember that local variables in Camunda are temporary and are linked to the life cycle of the process instance. When the process instance is terminated, the corresponding local variables are automatically deleted.

I hope that with this answer I was able to clear your doubts about this behavior.

William Robert Alves

Hello @WilliamR.Alves
Thank you for description in detail.

I don’t know this features that you mentioned about it were in the old version of camunda or not. I’m using camunda version 7.8.0 and after complete all steps and finishing the process instance, my input variable (local variable) is existed in the database yet! and exactly as you said I need to remove them for cleaning up the resource of variables at the end.

I have tried for cleaning this local variables with adding dynamic parser listener and doing what I need but local variables are not accessible in any camunda services too.

Hi @Amir_Roshan ,

personally I did not know of any automatic clean up of local variables. As far as I know there is no difference in the variable lifetime depending on its scope. Obviously all runtime data will be deleted on execution or activity instance end. Please correct me, if I am wrong, @WilliamR.Alves .

Also “global variables” updated via setVariable are global in context of the root process instance and all its child executions.They are not available across multiple root process intances.

To me, the only difference between, setVariable and setLocalVariable and respectively global or local variables is as follows:

  • Global variables are available throughout all executions and activity instances within the root process instance as global variables
  • Local variables are available to its execution or activity instance as local variable
  • Local variables are available to all child executions and activity instances as global variable

For some illustration check out my post here: LocalVariable API not work

In consequence local variables aim to not pollute the global variable scope and are useful as temporary variables for some local calculation or parameters for sub executions or activity instances.

Kind regards
Adagatiya

2 Likes

Hello my dear @Adagatiya !

Now you really left me with doubts hehehe :sweat_smile:, I may be confusing the behaviors of the local variable with some other technology.

I’ll check this further…
Thank you my friend!

William Robert Alves

1 Like