| 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 |
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.


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).
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").

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.

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.

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


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.

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 |
| Image | Explanation |
|---|---|
![]() |
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. |
![]() |
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 |
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.

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.
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.

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).

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).
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 are placed at the boundary of an activity and has the following logic:

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.
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.

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.
