My application expects a related group of events. I would like to construct a workflow that waits for all the events from the group to arrive (or times out), and then proceeds. Each group and each event have a UID associated with it. The events arrive at random times, and are unknown to my application until they arrive. Each event in a group has a specific, unique type that are known to the application, and each event has a the UID of the group it belongs to.
My first thought was
My concern is that the timing of events is random, and I may start 2 "group" workflows for the same group and process each group twice, or, worse, they may starve waiting for the correct messages. Aside from using Java to synchronize the "group" start, is there a standard way to do this within Activiti?
Cheers,
-dan
Solved! Go to Solution.
Hi Dan,
An interesting problem and actually one that matches a project we completed recently for one of our clients.
Ignoring the message receiver classes for which I imagine you will create a message driven bean, rest endpoint or other custom handler to call into the workflow engine.
Your description indicates that it is possible for other messages to arrive while the process is being started or while a given event is processed and it is therefore possible to lose these messages.
As such, you need to use a publish and subscribe pattern rather to simply throwing the events at the process engine and hoping they get caught.
On the first message for a given groupID start the process AND put the message into a list (you can use an in memory store or DB table, really depends on the scenario).
Then, when the process starts have it go out and look for messages (obviously there will be at least one) and retrieve them, basically a polling pattern, when all types are received, clear the group from the list and move on with the process.
This way we process as many messages as are available at any given moment and can't miss any since we are decoupled.
Hope this makes sense,
Greg
Hi Dan,
Looks like you are looking for the ability to start a process by an event message. Activiti provides 'Message Start Event' that allows you to start a process instance by a message. Have a look at the doc here Activiti User Guide
You would need to call the following APIs
ProcessInstance startProcessInstanceByMessage(String messageName); ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables); ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map<String, Object< processVariables);
The 'messageName' would be pre-defined in your process definition within 'messageRef' attribute of the 'messageEventDefinition'
However, looks like your scenario has multiple asynchronous events to determine when the process can be started
My application expects a related group of events. I would like to construct a workflow that waits for all the events from the group to arrive (or times out), and then proceeds
So I think you would need to implement custom logic for this. You would need to create a set of asynchronous calls to these events and have the process triggered in the callback of the successful calls. Within the callback, you then call the startProcessInstanceByMessage API.
Let me know if this answers your questions.
Thank you,
Thong Huynh
bp3
Hi Dan,
An interesting problem and actually one that matches a project we completed recently for one of our clients.
Ignoring the message receiver classes for which I imagine you will create a message driven bean, rest endpoint or other custom handler to call into the workflow engine.
Your description indicates that it is possible for other messages to arrive while the process is being started or while a given event is processed and it is therefore possible to lose these messages.
As such, you need to use a publish and subscribe pattern rather to simply throwing the events at the process engine and hoping they get caught.
On the first message for a given groupID start the process AND put the message into a list (you can use an in memory store or DB table, really depends on the scenario).
Then, when the process starts have it go out and look for messages (obviously there will be at least one) and retrieve them, basically a polling pattern, when all types are received, clear the group from the list and move on with the process.
This way we process as many messages as are available at any given moment and can't miss any since we are decoupled.
Hope this makes sense,
Greg
Greg,
Yes, that's it exactly. There may be two or more "messages" concurrently trying to start a workflow. I wanted to avoid race conditions, but like the idea of a workflow waiting for Activity messages to arrive, behind a gateway. Very clean compared to polling. Not afraid to poll, but would would have liked to avoid it.
Thanks for the help,
-dan
Yeah, it's a tough problem.
Honestly, other workflow engines (commercial) have an answer to this with what they call "durable messages", meaning you don't have to be listening for the message to act on it, if the process gets to it afterward, it is ok. I have been meaning to write something like this for Activiti, just haven't got to it yet.
Cheers mate and let us know if we can be of any help
Greg
Ask for and offer help to other Alfresco Process Services and Activiti Users and members of the Alfresco team.
By using this site, you are agreeing to allow us to collect and use cookies as outlined in Alfresco’s Cookie Statement and Terms of Use (and you have a legitimate interest in Alfresco and our products, authorizing us to contact you in such methods). If you are not ok with these terms, please do not use this website.