Limit number of concurrently running instances of a process definition

Context: Camunda BPM 7.6.0-alpha5, embedded process engine with Spring Framework, clustered deployment, one database

Is there a camunda-native way to limit the number of concurrently running process instances of a particular process definition? For instance with limit=1, only one running instance of that process allowed, specifically: new instance cannot be started if one running instance already exists, can though after that earlier running one is completed.

(Event listener with proper transaction attributes?)

1 Like

Hi,

You may be interested in this thread…

One way I would consider is create a DB resource eg new table called lock with a single row. Hence on instance start have a task update lock set locked = true where lock = false. If this succeeds, continue, otherwise abort. You also need a completion task - update lock set locked = false.

I suspect the pattern you are after is a network semaphore. Another approach could be to look at something like zookeeper

regards

Rob

Thanks Rob. How could we forget the feature of enforcing businessKey uniqueness in this regard! We’re doing this on-start-lock/on-complete-release staff right now. We’ll try both. Don’t wanna touch distributed lock and transactions for now.

With businessKey uniqueness turning on, the case limit=1 can be achieved, but then for all process definitions.

This may be a bit “hackish”?

But could you just create a script on the Start Event: Start Listener:

var instances = execution.getProcessEngineServices().getRuntimeService().createProcessInstanceQuery().processDefinitionKey("concurrentTest").active().count();

execution.setVariable("instances", instances);

if (instances > 1) {
   throw "too many instances are running";
}

and if you run through tasklist:

and through the API:

Note: the variable being set in the script is just for testing and seeing what was going on.

1 Like

Without race-condition your approach will do. By setting isolation level to serializable it might work too.

@kenix for this code example you will need to change the if statement to 0. if greater than 0. as the first running instance will have the instances count == 0.

We had the problem in the past, tried to find a small solution and took care about race-conditions by letting every instance start but exit after a first transaction if it was not the first started instance.
Of course you lose the nice immediate feedback not starting the instance at all.

@wke-rec, that’s a clever idea, with proper transaction attribute setting will work. For our case we need to check which instance has the currently smallest transaction number. However, we then have to take care of cleaning the audit trail and filtering out such instances from reports. A different feedback might be possible using modeling elements, but then the model will be “polluted”. What’s your opinion?

Yes, this needs to be added to the model. Depending on how you defined success of such a workflow and if you may have some other reasons for an abort already modeled, it might be not too much pollution.

Another idea could be using a “starter process definition” that just calls the real process definition you want to report on, using a call activity.

You can use a service task of type “External”. And then clear the topic one by one using camunda timer that triggers the delegate(lets call this topicDelegate) which has the code to clear the messages in the topic one by one with some delay.

Instead of a fixed delay you can make sure when a camunda process instance completes it makes some kind of entry in some table that you can check in the “topicDelegate”