Friday, January 4, 2019

A powerful and easy-to-use workflow engine



After research many open source workflow engines, I decided to roll up my sleeves and write one.
My workflow engine has some distinctive differences with open source workflow engines, perhaps the biggest one is on the abstract concept: at its core, my workflow engine consists only 4 things:

  • a step type that needs human action (a decision step type)
  • a step type that’s done by code (an execution step type)
  •  a transition that transits among steps
  •  some logic steps such as AND, OR, RETURN,Subworkflow etc

In contrast, BPMN has many more elements, check out example in BPMN 2.0 by Example: non-normative OMG document with BPMN 2.0 examples. Of course, in a BPMN internal implementation, one can still abstract things to a much simpler model, but intuitively BPMN is more complex and difficult for a novice user to understand. 

Below I will introduce how my workflow engine works. 

 

Decision Step

A decision step requires human action. When a process runs, the options for the decision will be presented at the top of the page – in a highlighted position grabbing a user’s attention, for example, in a case handling workflow, the decision waiting for a user to make might be: whether to submit or to escalate or to cancel. 



This is another difference with BPMN workflow. Human actions are highlighted in a prominent position; while in a BPMN workflow, there is no distinctive concept of “human actions” – again, one can choose to implement BPMN that highlights human actions, but BPMN doesn’t prescribe or emphasize this. In my experience, workflow is often used in processes that involves a lot of checkpoints which require human actions, highlighting them makes the user interactions easier.

To model a decision step:



  •   1 are the decisions a user can make.
  •   2 controls the visibility of the decisions. Sometimes, if some decision options are so sensitive that you don’t want certain users to see, you can input conditions here.
  •   3 controls whether you can act on the decision. E.g. “entity.impact===’Urgent’” means you can’t Escalate a case if its impact is not Urgent. entity is a special variable here referring to the form object that is associated with a workflow.
  •   4 controls where the decision options come from. If it is “SIMPLELIST”, you can input options here as shown in the graph; you can also select “SQL” and input a sql to get decision options.

On the security tab, you can control who can act on the decisions. 

  •     1 is a single user
  •     2 is a user group, which groups users based on some attributes of a user.
  •     3 is a user token, which is a special variable. The workflow engine provides some special variables to use, E.g. @{userId} is the id of the current user, @{step} is the current step.

On the notification tab, you can control email notifications:

  •  1 determines when to send email. It can be when the user makes a specific decision (Specific Result), or when the process gets to this step (Eligible), or when the step hits upon a specific error (Specific Error), or when a user makes any decision (All Results), or when the step hits upon any error (All Error).
  •   2 configures who to send email to. Just like in the security tab, you can User, Security Group or User Token.
  •   3 shows you can freely use special variables like entity and others to compose the content of an email.
  •    4 is to copy the current email. You can configure multiple emails for a single step. 

 

Execution Step

 

  •  1 An execution step executes code. Code can be of 3 types: simple Script, Java, and Composite Script.
  •   3 is an example of a Composite Script, which supports Java like syntax and special variables.
  •   2 determines when to execute code, “Immediate” means when the process gets to this step, immediately executes the code; “Manual” requires humans to trigger the execution of the code.
  •     If 4 is selected, this execution step will be run asynchronously. If you know the code inside this step will run for a long time, you can make this step run asynchronously. The next steps this step leading to will wait until this step finishes.

 

Transition


To add a transition, link two steps, and this window will popup:
  •    1 determines when to go through this transit. It can be when the previous step generates a specific result (Specific Result), or when the previous step generates any result (All Results)
  •     2 determines when the previous step hits upon a specific error (Specific Error), or when the previous step hits upon any error (All Errors)

 

Subworkflow

A simple subworkflow is, well, simple:

  •     1 choose which subworkflow to use. 

A loop subworkflow is more interesting:

  •       1 is to choose which subworkflow.
  •       2 is to configure what to loop on. In this example, the parent workflow wants to upgrade a set of VMs, the subworkflow will actually do the upgrade. entity.vms means the upgrade workflow will run for each VM. In runtime, the workflow engine will provide the subworkflow the current VM object, among other objects that subworkflow can get access to.  
  •      3 determines whether you want to run subworklows concurrently. E.g. if you have 10 VMs, you may want to upgrade 2 VM each time.
  •      4 determines whether to continue to run the remaining subworkflows when a subworkflow hits upon errors. E.g. if upgrading one VM fails, you can decide whether to upgrade the rest or abort.

 

And

·      

  •   1 is an And step. And is a logical step, and only will be transitioned if all the leading steps before it has been transitioned. In the above graph, step2 and step3 have a tiny lightening icon attached, meaning, they are run asynchronously (see Execution step)

 

Or

·   

  •  1 is a Or step. Or step is a logical step, and it will be transitioned if any step leading to it has been transitioned. In the above graph, step2 and step3 have a tiny lightening icon attached, meaning, they are run asynchronously (see Execution step)

Comparing with BPMN, my workflow engine is probably more intuitive, as it pacts lots of actions in one step (such as email notification, error handling etc). And because at its core,  it contains just two types of steps (Decision and Execution) and transitions, the implementation is not complex and relatively easy. 

 

 Example

Here is an example of a hotfix requesting workflow:


Technologies

UI uses Angular 6. UI is another difference with some open source workflow engines, which uses JSP and looks old and clunky. 

The backend uses Springboot.

 

Form Builder

A full-fledged workflow engine requires a form builder. I’ve intentionally made the decision to separate form builder with the workflow engine, because UI technologies involve faster than backend technologies, keeping them separated will ensure UI can be kept up to date. 

Form builder is still under construction, so stay tuned.