Correlate message for multi instance task

If you are generating the correlationId values inside each instance of the multi-instance, then just store those values as process variables within the Sub-Process. And everything should continue to work. You dont need to use Local Variables on the Catch Events.

1 Like

If inside “Start waiting” I will use process instance variable - it will be overwritten by another parallel subprocesses

public void wait(DelegateExecution execution) {
    UUID correlationId = UUID.randomUUID();
    execution.setVariable("correlationId", correlationId.toString());
    log.info("Start waiting correlationId = {}", correlationId);
}

If inside “Start waiting” I will use local variable - it will not be available in message events

public void wait(DelegateExecution execution) {
    UUID correlationId = UUID.randomUUID();
    execution.setVariableLocal("correlationId", correlationId.toString());
    log.info("Start waiting correlationId = {}", correlationId);
}
1 Like

You can do something like this:

In the SetVar script i have execution.setVariableLocal('dog','cat');.

and you can do a correlation using process variables:

doing /message in the REst api:

{
  "messageName" : "m1",
  "processCorrelationKeys" : {
    "dog" : {"value" : "cat", "type": "String"}
  }
}

Yes, I see. It’s the same as my option with receive task. The main point to remove event base gate way.
Thank you a lot for your help.

Try with the event based gateway. I believe it should still work

If I try to set local variable and then correlate with process instnace variable:

public void wait(DelegateExecution execution) {
    UUID correlationId = UUID.randomUUID();
    execution.setVariableLocal("correlationId", correlationId.toString());
    log.info("Start waiting correlationId = {}", correlationId);
}

public void correlate(String correlationId) {
    runtimeService.createMessageCorrelation("success")
            .processInstanceVariableEquals("correlationId", correlationId)
            .correlate();
}

I got following error:

org.camunda.bpm.engine.MismatchingMessageCorrelationException:
ENGINE-13031 Cannot correlate a message with name 'success' to a single execution.
3 executions match the correlation keys:
CorrelationSet [businessKey=null, processInstanceId=null, processDefinitionId=null,
correlationKeys={
    correlationId => Untyped value 'aff42bd6-b333-428f-b311-7784fd1aec6d',
    isTransient = false
}, localCorrelationKeys=null, tenantId=null, isTenantIdSet=false]

That’s because you are using correlate rather than correlateAll see the other methods and the java doc. Correlate only correlates to a single instance. You need to tell it to correlate to all matching instances

Yes, but I have 3 parallel executions, and get 3 callbacks for each execution. So I should correlate only one execution per callback.

@thedenische can you double confirm that the correlationId value in each of your sub-process instances are different values?

Yes, correlationId has three different values for each multi instance subprocess, and for any value I get this error, when correlating message.

Feels like a bug then… Can you remove the event gateway, and just have a parallel gateway, and see if it works? I know it wont be a functional process as the parallel will create two tokens (one on each catch event), but we just want to see if its the event gateway that is breaking things.

I replaced event based gateway with parallel gateway and still get the same error.

not near a computer to test, so just giving you troubleshooting questions for now:
If you remove the multi-instance, and just have a single sub-process, does it work? If yes, then same scenario but activate two entirely different instances of the parent process, and test against, does that work?

Okay found the issue. It is because a embedded sub process is a activity and not a different process. Best solution I found was to use a call activity. You can still save your process levels variables for the sub process that was started by the call activity. And you can continue to use the event gateway.

Thank you a lot.
Yes, I could switch to Call Activity as a workaround. But looks like it will be more suitable to use AbstractBpmnActivityBehavior or External Task

Your model is very close to a External task pattern. So if you can use that all the better.

1 Like

Hi @StephenOTT
Coming back to this example is it possible to get a list of local matches from a query?
So for the following array I’d expect to get back two instances, however this will return the four instances.

var array1 = ["dog","cat","horse","cat"]`

Something like the following, but actually works :slight_smile: ?

List<Execution> list = runtimeService
                .createExecutionQuery()
                .messageEventSubscriptionName("MyCustomMessage")
                .processVariableValueEquals("customMatchVariable", "cat")
                .list();

I couldn’t find an equivalent ‘processLocalVariableValueEquals’ for this example.

Any suggestions about how I could do this?

Can a message start event or catch event have local variables ?

Not sure what you mean but I’m using the original example you provided, to understand how to match against local variables in a query.

The correlation example you provided, is similar to what I need, but I only need to get back the process executions. I don’t want to correlate. The input did the trick, thanks.

Thus my question is, you have say four instances within the multiple-instance task ( e.g. “dog”,“cat”,“horse”,“cat”), how do I match against the local variable, say ‘cat’ and return only the matched instance(s).

So for example, How to find a multiInstanceBody Task with a specific variable value
The following returns a list of instances.

List<Execution> list = runtimeService
            .createExecutionQuery()
            .messageEventSubscriptionName("MyCustomMessage")
            .processVariableValueEquals("customMatchVariable", "cat")
            .list();