cancel
Showing results for 
Search instead for 
Did you mean: 

Signal/Cancel running process

mbonato
Champ in-the-making
Champ in-the-making
I'm trying to find a good/suitable process design for a 'cancelable' process that involves some asynchronous tasks and a message receive task. The process may be simplified to the process shown in the following figure.

[img]http://snag.gy/BBBfQ.jpg[/img]

What makes things complicated is concurrency. The process is started in one thread, tasks are executed asynchronously in a background thread and the cancellation occurs in another thread.

First I thought about using a subprocess with a signal boundary event. This works as expected, as long as there is no concurrent access to the process. However, when the signal is send while task A is still executed the thread ends up in a optimistic looking exception when trying to commit the transaction. Unfortunately, task A also involves non-transactional actions. So I cannot rely on the transaction rollback, but need to know whether task A has started/completed. Synchronizing threads is not an option, since the application might be deployed on a cluster, with Activiti running on multiple JVMs.

My second thought, was to set a process variable and use exclusive gateways between the tasks. Setting a new process variable does not seem to end up in optimistic locking exceptions, so the tasks can finish normally. When a gateway is reached and the process has been canceled in the meanwhile, the execution diverts and rollback actions can be performed by another task. The drawback of this solution is, that if task B has already been reached and process execution waits for the message being received, I still need a signal to terminate it.

Any suggestions for more elegant solutions?

3 REPLIES 3

jbarrez
Star Contributor
Star Contributor
Besides cluster-wide locks, i think there is no other decent solution technically.
Note that a cluster-wide lock is not as scary as you might think: it might be just an entry in a database table where one cluster node has to 'take ownership' of before it can execute the process instance.

Solution 2 sounds like it will work, but it's a lot of work to get right I think.

mbonato
Champ in-the-making
Champ in-the-making
Thank you for your quick response!

I already thought about using database based locks, but I'm not sure how to handle asynchronous job execution. How can I make the job acquisition thread respect these locks?

jbarrez
Star Contributor
Star Contributor
Hmm, in that case , in your service task, you'd need to use another transaction probably (ie also another transaction manager) to do those locking.

Another option which migh be easier development wise (but a little bit heavier deployment-wise) is to use distributed locks like for example used in Hazelcast (and alternatives)