Version Date Notes By
1.0 2020-11-25 Initial release ROB
1.1 2020-11-26 Added section detailing how token processes and token process objects are created, what they store and what they represent as far as running a bpmn process is concerned ROB
1.2 2021-02-05 Added information about bpmn collaboration ROB

Introduction

The SGU Processes engine (SGU for short) is what handles the execution of the bpmn process (or processes, if there are sub processes). This engine is only concerned with the progress of the flow in the bpmn diagram and not with whatever happens inside each activity (each activity has it's own implementation or systems, and the process engine is only waiting for a "done" signal to continue).

The process engine will follow the BPMN 2.0 Specification, but for now it is incomplete so it only partially follows the specification (there are components missing).

For an SGU bpmn process to be valid, it requires at least one start event (of any available type) and one end event. Furthermore all components in the bpmn diagram require a valid path to the end event otherwise any token processes running through it might throw an UnableToResolveToExitException and not complete properly.

Invalid process - Has no exit

Invalid process - Has no exit

Invalid process - Some components cannot resolve to an exit

Invalid process - Some components cannot resolve to an exit

Barring the limitations above, all other components can be added in between, each with it's own required information / validations (more details in the bpmn components page).

High level functioning of the SGU process engine

Basic functioning

In general, the SGU process engine will "catch" the start event (that is to say any process with a start event of the same type as the event, and fullfilling all required validations for that event) and create a new token process. The token process represents an instance of a process execution.

The token process will then create a token process object to track the interaction between the token process and each individual object in the bpmn diagram (one token process object per bpmn object per loop).

Processing will halt at that "branch" until the token process object indicates it has been resolved (for example a user form is considered resolved when all forms stop having validation errors AND the user has clicked "Submit").

Example process - Halt at user form

Example process - Halt at user form

When a given bpmn object is considered resolved, a list of next valid bpmn objects are generated and a new token process object is created per valid next object.

How each task is resolved by the process engine

How each task is resolved by the process engine

The only exception to this behavior is if the token process encounters a gateway, in which case the next bpmn objects will be determined by a WeFlow script or if the token process encounters an end event, which returns no further objects, ending that "branch" of processing.

Example process - Completed process via invalid information path

Example process - Completed process via invalid information path

One processing "branch" reaching an exit event does not stop other branches unless the end event is a "Terminate end event"

Example process - Two branches can operate simultaneously without interference. One reaching the end does not halt the other

Example process - Two branches can operate simultaneously without interference. One reaching the end does not halt the other

Example process - The first branch reaching a terminate event cancels all others. The token process is considered complete.

Example process - The first branch reaching a terminate event cancels all others. The token process is considered complete.

Token process and token process objects

Intro

When a process is selected by a triggering event (user clicking on "Start process" or timer event firing, etc ...) a new token process (A laravel model / record in the t20_token_process table) is created. This model represents a single instance of a process execution and has attached to itself all the variable instances that will be created during the process.

On creation, a new token process code will be generated to uniquely identify the instance for the user (it works similar to document module where the string 'CODE-###' is transformed into 'CODE-001' for example).

The processing engine will then generate a list of bpmn objects connected to the start event that was fired. Please note that the process can have multiple start events of diferent types, and that the event may be caught by one or more of them but maybe not all of them.

Process with multiple start events - Not all starts are required to fire, diferent conditions could represent diferent methods to resolve the same process

Process with multiple start events - Not all starts are required to fire, diferent conditions could represent diferent methods to resolve the same process

Once that list of bpmn objects is created, for each of them the SGU process engine will create a new token process object (Also a laravel model / a record in the database table t20_token_process_object), and set it up with the following values.

Column Value
status_id 2 In execution - Represents the state of the task
token_processing_count Stores the ammount of times the associated bpmn object has been executed
token_step_counter Stores an individual global incrementing number (for each token process the number increments by 1 per token process object). Even parallel tasks will get diferent numbers in this column and this number keeps incrementing until the process completelly exits.
token_loop_uid stores a number that is unique for a given self itteration. Since the bpmn diagram can loop in on itself, this column can have multiple uids for the same bpmn object (the diagram can loop and the object can self itterate)
token_loop_itteration Stores an incrementing number for how many times that bpmn object self itterated for the same token_loop_uid. This number resets when token_loop_uid changes. For bpmn object that don't self itterate this column is null.
from_token_object_id id of the token process object whose next bpmn objects list originated this one

Token Loop columns detail

Image Explanation
Loop variables explanation 1 On the first execution of an activity that self itterates, the token_loop_uid is set and token_loop_itteration is given an itterated counter (+1 per itteration). For example uid = 1 and itteration = 1,2 and 3 if there are three users.
Loop variables explanation 2 On the next execution of the activity a new uid is generated (not garanteed to be sequential, just unique) and the itterator counter is reset. For example uid = 2 and itterator = 1,2 and 3

Process end

Once a token process object is resolved, it is marked as complete and the next set of bpmn objects is generated. For each of those, a new token process object is created (so bpmn objects that are not either completed or in execution do not have a token process object).

In the SGU processing engine, the processing is done as a "wave" where the execution is moved as far as it can go and then waits for the respective system (WeFlow script, user input, message system, etc...) to report completion to continue.

Process demonstating where token process objects exist and in what state

Process demonstating where token process objects exist and in what state

Once the execution reaches an exit event it will check if there are no token process objects in execution. If there are none or if the exit event is a terminate exit event, then the token process itself is marked as complete. The process is done, all tasks in all "branches" where the process has flowed, have completed, and the token process is moved to the historic list.

Loops and iterators

SGU process engine allows for looping diagrams to be explicitly drawn. Every time a token process "passes" through a bpmn object it generates a new token process object. That means that in a looping diagram there are (potentially) multiple token process objects per bpmn object.

Example of process with a loop

Example of process with a loop

There is also a bpmn notation that is used by SGU to "self iterate" a given activity until an exit condition is fullfilled. For example for every responsible generate a form for them (one for each).

Example of process with itteration

Example of process with itteration

It is possible to combine both methods of looping in the same bpmn diagram, so in the database these indexes are stored separately.

In both of these cases, the responsability for ensuring that an exit can be found is on the creator of the process (individual token processes will throw an exception depending on where the problem is).

Interaction with token process variables

Variables are defined by the process creator and used by the various activities (User, Script, Service, etc...). There are a few simple rules governing instancing variables by a token process.

If a variable definition is a root variable or a single relation variable, then it is a singleton (only one instance of that variable definition may exist per token process). Otherwise you can have many of them.

The first activity to request a singleton variable instances it and subsequent requests modify it (overwritting it's values).

Boundary events

Boundary events are placed at the boundary of an activity and has the following logic:

  • If the event is fired and the token process is executing there, then the flow of the process is redirected to the boundary path.
  • If the event does not fire or the token process is not executing there, then nothing happens (flow proceeds as normal).

Example of path taken when boundary event fires

Example of path taken when boundary event fires

In the example above, when the token process enters the activity "Fill in this form" a 30 minute countdown starts, and if the user completes the form before it ends then the process continues to "Thank you", otherwise the "Fill in this form" is canceled and the activity "Complain to manager" starts.

This is the funcionality of the boundary event. It interrupts the activity it is attached to, and moves the token process down the new path.

Enbedded sub processes

Tecnically speaking the sub process is an independent process (stored separately in the database) with parent_id set to the main process.

Enbedded subprocesses have an independent token process but share the same variable instances (that means that if the sub process modifies a variable, that modification carries over to the main process).

When the sub process is entered, the parent execution halts and when a sub process exits, the parent process continues it's execution. The activity that is the container of the subprocess considers itself concluded when the first exit event is reached in the sub process.

The sub process (as well as all other activities) can have a boundary event to catch events originating from inside the activity or from the process itself, allowing for alternative paths.

Enbedded sub process example - inside process is an independent token process so execution count restarts from one.

Enbedded sub process example - inside process is an independent token process so execution count restarts from one.

Bpmn Collaboration

Bpmn collaboration allows a bpmn process to be expressed as the interplay of multiple processes (drawn as pools) and may further separate the responsibles through the use of lanes instead of direct responsibility attribution.

The current implementation allows the process creator to attribute responsabilities to the lane or pool (saving the effort of setting the responsabilities to each activity).

It also implements message flows, allowing message events to connect visually (and functionally) across pools.

Collaboration example - Point 1 - Responsabilities can be attributed to the lane and apply to all activities in that lane. Point 2 - Message flows trigger message events across pools.

Collaboration example - Point 1 - Responsabilities can be attributed to the lane and apply to all activities in that lane. Point 2 - Message flows trigger message events across pools.