Processus Interruptus! Interrupt Parallel Workflow Tasks


Thu 10 November 2016 By Josh Fletcher

Introduction

The Nuxeo workflow engine supports parallel tasks; in fact a default workflow that includes parallel tasks is provided in the core platform. Parallel tasks are an excellent way to increase user productivity by allowing users to complete tasks without needing to wait on each other.

Nonetheless there is a common need to be able to “interrupt” workflow tasks; really to be able to branch during a task and choose different paths. Task branching is easy for serial tasks, you just need to define the necessary transitions (and the conditions for those transitions).

Typically a parallel workflow task will seem to not resolve until all of the participants have completed their task; the workflow engine appears to wait until all tasks are complete and then chooses a transition based on the results. There is actually a bit more going on, however, so this time around we’ll take a look at how one might interrupt a parallel workflow task.

Overview

A “parallel task” is just a different node type in Nuxeo Studio, labeled as “Multiple Tasks”:

The configuration of a Multiple Task node is the same as for other nodes at a high level. It has variables, forms, transitions, and escalation rules just like any other node. The main difference is that when the workflow engine encounters this type of node it creates a separate task for each of the assignees, and by default a transition is not chosen until all tasks are complete.

Use Case

Given a “review” or “approval” step in a workflow, I want to be able to send the document back to the author immediately if there is something that’s absolutely unacceptable. In this case there is no reason to wait for the other assignees to approve the document, I already know it needs to be revised.

Another way to look at this use case is to give a “super user” the ability to interrupt a parallel task at their discretion.

Workflow

Here is a simple workflow for illustration:

In this case I want the “reject” transition to be followed if any user clicks the reject button.

Task Interruption

There are a few important items that make this possible:

Automatic Transition

Automatic transitions only require that the condition bet set to “true”:

Exclusive Node

To make a Task an Exclusive node, locate the checkbox on the Transitions tab for the Task:

When workflow engine runs an exclusive node, it evaluates the transition one by one and stops a soon as one of the transitions is evaluated to true. This means that the “reject” transition will only be used if all others fail.

Escalation Rule

The Escalation Rule should fire if the user clicks the “reject” button; so the Condition is like any “normal” transition, e.g.:

NodeVariables["button"]=="reject"

The automation chain used by this escalation rule simply forces the Workflow engine to re-evaluate the transitions via the Workflow.ResumeNode command:

- Context.FetchDocument
- Workflow.ResumeNode: {}

Once the chain is executed, the workflow engine evaluates the task’s possible transitions. It’s worth mentioning that the condition for the “approve” transition is something like:

@{NodeVariables["tasks"].getNumberEndedWithStatus("to_FinalReview")==NodeVariables["numberOfProcessedTasks"]}

If any of the outstanding tasks are incomplete, this condition evaluates to false and the workflow engine follows the automatic “reject” transition because it’s an exclusive node.

Tip: Don’t forget to declare a valid lifecycle transition for this behavior if lifecycle states are changed during this process.

Bonus: Proportional Task Resolution

It’s possible to achieve some interesting results by adjusting the condition for a transition in a parallel task. For example how about following a transition if at least half of the assignees selected the “NotLiable” action? Here is the expression:

@{NodeVariables["tasks"].getNumberEndedWithStatus("NotLiable") / NodeVariables["numberOfProcessedTasks"]>0.5}

Rather than interrupting the task, this expression supports a “voting” system; it only evaluates to true if more than half of the participants choose the “NotLiable” transition. Even better, in the absence of an exclusive node, this means multiple transitions can be followed from the same task.

Conclusion

Nuxeo’s Workflow engine is incredibly flexible. It’s really amazing to be able to take a seemingly natural request from a customer, “I want to be able to reject a task and not waste everyone’s time”, and model that directly in the configuration.

You are never locked into a certain behavior, even at runtime. With so many options for altering the path through a workflow, the engine is truly capable of supporting modern business processes and enabling digital transformation.


Tagged: Workflow, Nuxeo Studio
Check out the features of our latest Nuxeo Platform Download Nuxeo