Enter Parallel actions
Parallel actions in Nintex allows a workflow to take two or more paths simultaneously. There are at least two situations where this comes in handy.
The first situation is to help with workflow organization:
In the case above, these actions are set into parallel because it lets a workflow designer understand what is happening in this workflow in an easier way by conserving screen real-estate. Functionally, these collection operations could have been performed sequentially without the use of run parallel actions and there would be no difference in how the workflow worked.
The second place where parallel actions are useful is when a shape has a wait condition but the workflow needs to complete other actions while waiting for that event. Examples of this include: adding reminders to review tasks (see below), waiting for an item update action to complete, and requesting multiple tasks in parallel.
Parallel action deficiencies
The problem with parallel actions is that if a branch doesn’t complete because a wait condition goes unfulfilled, the workflow will not proceed. While most programming languages have a go-to, break, or continue statement, there is no equivalent action in Nintex. Actions like the State Machine's “Terminate State Machine” action only really execute at the bottom of the state branch.
I recently came across a problem where a process would need to wait for seven days, or until a checkbox in a form to be checked. The requirement was to have the workflow proceed as soon as the first condition was met. The first version of the workflow is below. The problem is that having a pause on one side and a wait for on the other until both events have happened, instead of just one.
But there's a solution
We can use a bit of task cleverness in order to have one branch execute others! What we need is a way to exit from a set of parallel actions when only one of the branches is true. There is no way currently in Nintex to exit a set of parallel actions, but by generalizing the task reminder example above, we can accomplish a similar goal.
Nintex provides one set of actions where the execution can be controlled by other actions: the task. Specifically, Request Review and Request Approval tasks provide visibility to an action ID that can be used to reference and execute a task in a workflow. By using tasks as described below, we’ll be able to control when multiple branches complete.
The idea is as follows:
Instead of using pause for actions, create dummy tasks to wait and complete when desired, allowing us to proceed on demand.
So, to start:
We have a parallel action with multiple branches, and more than one has a wait condition. In order to control the action on the left branch from the right branch, we replace “Pause For…” shapes with the set of shapes shown below.
Replace a Pause for with a parallel action holding a dummy task on one branch, and a complete task on the other branch
The dummy task should have an action ID assigned as shown below and the Complete Workflow task should match it.
Then, add a complete task shape to the right branch as shown below so that once the Item Update action completes, the left branch will complete immediately (or after 5 minutes as a result of SharePoint).
In order to move past the right branch of the parallel action, we can update the item in the workflow, as shown below.
Why not loop?
A more popular solution to this problem is to institute a loop that will run on a time interval, for example every five minutes, creating Run If actions, and checking the conditions in the parallel action branches and exiting once a condition is met. This is a solution to the problem, but falls short in two areas:
- By running a set of actions many times, the history list grows quickly, leading to slowness due to indexing, and loss of value during history list / verbose logging inspection because of the number of entries. At five minutes per loop and five days, the loop will execute 60 minutes / 5 minutes per loop x 24 hours x 5 days = 1440 loops to complete the leftmost branch of the example above.
- From an infrastructure perspective, slowness on the server at any point in the day, given that the workflow is running essentially continually, can cause the workflow to fail due to inability to access server resources. For high-value workflows, this isn’t an option.
Summary and considerations
What we have built is a workflow that will continue as soon as first of two conditions is satisfied. There are a number of ways this solution can be used beyond what we’ve covered: In order to send task escalation emails to an initiator rather than approver, or on parallel actions with multiple branches. In order to integrate this into a solution, one suggestion would be to create a view on the task list that hides the dummy tasks assigned to the system account.