cancel
Showing results for 
Search instead for 
Did you mean: 

Non-linear workflows.

amackenz2048
Champ in-the-making
Champ in-the-making
We're designing an HR system that will require that all change requests to user data be approved through a multi-step approval process (5-7 on the high-end).  These requests would have slightly different stages for approval depending on the type and other data.

Our stages would be sequential (e.g. "stage 1" would need to approve before the people at "stage 2" would approve).  BUT the workflow wouldn't necessarily be linear in that we want users to be able to "reject" an approval back to any prior stage - and some users will be authorized to approve beyond a single stage.

I'm not sure how handle this gracefully within the Activiti workflows.  I've come up with the following but it's a bit unwieldy from a user perspective (e.g. it doesn't show the "linearity" that they feel is part of the process).  But short of a fully-connected graph which would be MUCH worse IMHO I'm not sure on how else we could implement these requirements.

https://www.dropbox.com/s/k9w4gcit07xnz82/ProcessA.png

Basically the "router" gateway would take as input which stage the user indicates the task should go and forward processing to that state.  We would need to provide logic giving the users only the stages they are allowed to choose from as well as validating this at runtime as well.

I'd love to get any feedback on best practices for this sort of flow. 
6 REPLIES 6

jbarrez
Star Contributor
Star Contributor
A full connected graph is indeed something you don't want. Because than there are better solutions than Activiti out there.

It's not an easy thing to model in BPMN, that's for sure.
To get more 'linearity' in your process, why dont you put an exclusive gateway after the usertask like this

phase 1 – ex_gw - ok -> phase2
                            – reject –> router

You could get rid of the gateway and have the sequence flow directly out of the task instead of using an exclusive gateway.

amackenz2048
Champ in-the-making
Champ in-the-making
When you say "You could get rid of the gateway and have the sequence flow directly out of the task instead of using an exclusive gateway." do you mean that I could just have criteria on the arrows leaving the user tasks?  I'd wondered whether that would work.

Another idea I had was whether there was a way to have a usertask sort of "okay itself" under certain circumstances.  That would keep things simpler looking, though could be misleading I suppose since one would ordinarily expect control to stop there…

trademak
Star Contributor
Star Contributor
Yes, you don't need to include the exclusive gateway, the conditions are checked either way. However when you don't use an exclusive gateway and multiple conditions evaluate to true then you get parallel executions. I don't think I understand your question about a user task "okay itself". Can you explain that a bit more?

Best regards,

amackenz2048
Champ in-the-making
Champ in-the-making
Ah, okay - that makes sense of the conditions.  Very interesting about the parallel workflows. 

By "okay itself" I mean that if an incoming parameter or value is set then the task would "complete itself" I suppose would be the better term to use.  Rather than requiring a user (or code) to complete that task.

For example.  You have three stages (A -> B -> C).  If under some circumstances you wanted processing to skip "B" then you'd put a condition on an arrow from A->C or through an exclusive gateway.  I was thinking in my "fully-connected" use-case whether it would be possible to have processing flow from "A" to "B" but for "B" to "recognize that this stage is not necessary" and flow automatically to "C".

Though now that I think about it…   "A" "B" and "C" could be script stages or something rather than user stages couldn't they?  And I could have them conditionally send the flow "forward" or "backward" or to a User Task as necessary.   Something like this:
https://www.dropbox.com/s/2ah7n5tdrc8hcgj/multistage_activiti.png

The script tasks will inspect the "target stage" parameter and promote/demote as necessary.  This also keeps the "appearance" of a linear promotion/demotion structure. 

trademak
Star Contributor
Star Contributor
I don't know the fine details of your use case of course, but this seems to be a good solution.

Best regards,

jbarrez
Star Contributor
Star Contributor
Yes, that is something you could do.
Another, maybe easier option is to have an external mechamism that you trigger by firing an event from a task listener.
That external mechanism can then decide to complete the task automatically for you.