Handling variables with concurrent message event subprocesses

Andy Rusterholz: Hi folks, I have a question about variable scopes. I’ve looked over the documentation but it doesn’t address my particular question. We have an Event Subprocess that is triggered whenever a user sends a chat message (see image). We run that message through a service task which determines whether the content of the message is appropriate or not. However, a user may send a second (or a third) chat message before we have finished processing the first one. So this subprocess might be executing multiple times in parallel. How do we ensure that the subprocess for the first chat message fully executes with the variables from the first message received event, while the subprocess for the second chat message fully executes with the variables from the second event, and so on?

Andy Rusterholz: Hi folks, I have a question about variable scopes. I’ve looked over the documentation but it doesn’t address my particular question. We have an Event Subprocess that is triggered whenever a user sends a chat message (see image). We run that message through a service task which determines whether the content of the message is appropriate or not. However, a user may send a second (or a third) chat message before we have finished processing the first one. So this subprocess might be executing multiple times in parallel. How do we ensure that the subprocess for the first chat message fully executes with the variables from the first message received event, while the subprocess for the second chat message fully executes with the variables from the second event, and so on?

Andy Rusterholz: I’ve looked at https://docs.camunda.io/docs/components/concepts/variables/#variable-scopes, but it doesn’t say anything about scopes of multiple invocations of a subprocess.

Andy Rusterholz: I’ve also looked at https://docs.camunda.io/docs/components/concepts/variables/#output-mappings, but it doesn’t say anything about how you might map an output variable to a specific scope.

Andy Rusterholz: It seems like we would need to map the variables from that Message Received event to a differently-named variable every time it’s executed, which isn’t covered in the docs.

Andy Rusterholz: I also briefly wondered whether we can map variables to dynamically-determined elements in a FEEL context: https://docs.camunda.io/docs/reference/feel/language-guide/feel-data-types/#context

Andy Rusterholz: But if that is supported, the syntax for it does not seem to be documented anywhere

Andy Rusterholz: If there is a way to specify in an output mapping that you are mapping it only to the scope of the individual invocation subprocess, that would be ideal, but again, I can’t find it documented in any of the above places

saig0: Hi Andy :wave: Thanks for raising this up.
The docs of the event subprocess mention that
> Input mappings can be used to create new local variables in the scope of the event subprocess. These variables are only visible within the event subprocess.
A similar idea is described in more detail for multi-instance activities.

saig0: The idea is to define an input mapping on the event subprocess. The mappings initialize the variables, for example, with null, and prevent that the variables are propagated to outside of the event subprocess. As a result, the variables don’t overwrites each other.

saig0: Does this help you?
I’m aware that this should be explained better in the docs :sweat_smile:

Andy Rusterholz: Hi Philipp!

Andy Rusterholz: This is somewhat helpful, thank you. I see how defining an input mapping on the subprocess will ensure that the variables are then only visible within that subprocess.

Andy Rusterholz: However, I’m still confused / concerned about whether those variables will be immediately overwritten as soon as a second chat message received event occurs.

Andy Rusterholz: Do we need to mark the event subprocess as a multi-instance activity in order for it to be executed in parallel whenever that event is received?

Andy Rusterholz: The problem with that is that there is no collection for the activity to iterate over. The Multi-Instance docs that you linked me to above say:
> A multi-instance activity must have an inputCollection expression that defines the collection to iterate over (e.g. = items). Usually, it accesses a variable of the process instance that holds the collection. The expression is evaluated on activating the multi-instance body. It must result in an array of any type.

Andy Rusterholz: But in this case we don’t have a collection – we want the subprocess to be executed once for each time that the event is received, with the variables that arrived with that event, in parallel.

Andy Rusterholz: If we put an input mapping on the subprocess, that will keep those variables from “leaking” into the global scope – but then, are they still all on the same subprocess scope, so that every time an event arrives it overwrites the previous variables in that single subprocess scope?

Andy Rusterholz: The page on Event Subprocesses does not say anything either way about invoking such a subprocess multiple times in parallel with each other.

Andy Rusterholz: @Kevin Mook attn

Kevin Mook: it’s my understanding that each subprocess “thread” will have its own local variables and local variables set in one thread won’t affect other threads (even if they’re in the same process instance). Is that correct?

saig0: > Is that correct?
Yes, kind of. But only if the variables are declared/instantiated locally by defining input mappings on the event subprocess.

saig0: > If we put an input mapping on the subprocess, that will keep those variables from “leaking” into the global scope – but then, are they still all on the same subprocess scope, so that every time an event arrives it overwrites the previous variables in that single subprocess scope?
No. The variables are defined in the scope of the element instance but not an the element itself.

By using the input mappings on the event subprocess, the variables are created as local variables of this instance of the event subprocess. Each instance of the event subprocess will have their own local variables that doesn’t overwrite each other.

Kevin Mook: aah, I see. Thank you!

Andy Rusterholz: Thanks Philipp!

Andy Rusterholz: > in the scope of the element instance but not the element itself
That makes sense and I understand the distinction.

Andy Rusterholz: One last question if you don’t mind –

Andy Rusterholz: if I use an input mapping on the subprocess to define an empty FEEL context, like this:

Andy Rusterholz: can I then use input mappings into that context on the event that starts the subprocess, like this:

Andy Rusterholz: and have them stay local to the subprocess instance, because the entire FEEL context is local?

saig0: > can I then use input mappings into that context on the event that starts the subprocess
yes :+1:

> have them stay local to the subprocess instance, because the entire FEEL context is local?
yes :+1: the variable message is created as local variable of the scope of the element instance of the event subprocess. since the variable is a context, all properties/fields that are created by an input mappings belongs to the variable

Andy Rusterholz: Perfect. Thank you so much for helping clarify all of this!

Note: This post was generated by Slack Archivist from a conversation in the Zeebe Slack, a source of valuable discussions on Zeebe (get an invite). Someone in the Slack thought this was worth sharing!

If this post answered a question for you, hit the Like button - we use that to assess which posts to put into docs.

2 Likes