LSPS documentation logo
LSPS Documentation
Model Instance

When you create an instance of a Model, the execution of the Model instance is managed by the execution engine based on the underlying Model stored in the Module Repository of the engine. The Model instance itself holds only its properties, information about its parent Model, and contexts with runtime data. The contexts are created based on elements that represents a namespace in the Model: every Module instance, every process instance, every sub-process instance, etc. has its own context;

Note: Before you can create an instance of a Model, you must upload it to the LSPS Server:

Note that if an executable Module imports other executable Modules, all Modules are instantiated as Module instances of one Model instance and start their execution.

modelinstance.png
Structure tree of a Model instance

If you want to inspect the exact structure of a Model instance, you can export a Model instance to XML, for example, from the Management perspective of PDS.

Transactions in Model Instances

When a Model instance is executed, its execution is split in transactions: the model instance status is persisted on every transaction commit. Note that database transaction boundaries are bound to session boundaries.

When a model is instantiated, the following happens:

  1. All its executable modules are instantiated.
  2. The first database transaction for the model instance is created.
  3. All BPMN and Goal processes in the executable modules are instantiated including any imported processes.
  4. On Goal processes, all top goals are triggered and become either ready or running if their precondition evaluates to true. The running Goals trigger their sub-goals or plans.
  5. Tokens are generated on all start events of the relevant process instances and on activities with no incoming flows. Every token is "moved" as far ahead as possible, that is, until it hits a wait point. A wait point is considered the following:
    • asynchronous task (user task, web service task, etc.)
    • intermediate event that requires a time slip (timer; signal, if the signal has not yet been received, etc.)
    • parallel join gateways that wait for a token

All moves of all tokens comprise one EJB transaction. The transaction is committed or rolled back and closed along with the session and the status of the model instance is persisted.

Important: Instances of shared Records are persisted in the Model instance as the entities' primary key and record type: however the value is stored in the respective database table and can be used by other Model instances or systems. In every new transaction, the system fetches the values of the shared Records from the database. Therefore consider the possible performance impact when working with large amounts of record instances.

If some tokens remained in the model instance, the model instance remains in the RUNNING state, but no actions are performed, the model instance is invoked (woken up) when some of the following happens:

  • A human task is submitted.
  • A Timer is triggered.
  • A condition with a shared record is met.
  • A signal is received.
  • A web service request/response is received.
  • An asynchronous task is triggered.
  • An Admin action occurs (an expression is evaluated, a context value changed, etc.).

Transactions in a Model instance with two Process instances

The first transaction includes generating of tokens on None Start Events and moving them to the closest wait points; in this case, 3 human tasks. The system then waits for the tasks to be submitted. Note that the order of the transactions is just an example order and it depends on the order in which the human tasks are submitted and the condition evaluation time.

transactionExample.png
Transactions in a Model Instance
On model instance invocation, the following happens:

  1. A new transaction and session are created based on the persisted model instance data. The persisted model instance data includes:
    • tokens with their positions
    • execution context (variables, referenced values, shared records)
  2. Every token is "moved" as far ahead as possible until it hits a wait point.
  3. Signals are handled, goals activated and deactivated, values changed, etc.
  4. Every token is "moved" as far ahead as possible.

That means that an invocation is in general identical with one transaction; however, if a transaction can include a custom object, such as, a function, which can create its own transaction. Such a transaction is still part of the same invocation.

The transaction is committed or rolled back and closed along with the session (the status of the model instance is persisted).

Execution Levels

A contexts of a Model instance can exist on different execution levels. Execution levels allow an element to have different context data on different levels and so to have different "versions" on runtime.

The execution level of the model instance, called the base level or 0 level, holds the "real" model instance contexts; consequently, for example, changes on Shared Records on this level are reflected instantly in the database.

The structure of execution levels is hierarchical: levels created on top of the base level are denoted as 0:1, 0:2 etc. Levels created on top of the level 0:1 are denoted as 0:1:1, 0:1:2 etc. Changes performed in 0:1 are visible only in 0:1 and in its child levels. However, the changes are not visible in the base level or in the other levels that are on the same level in the hierarchy (0:2, etc.).

Contexts of non-base levels store only values that are changed: Other values are not stored.

Data of contexts of non-base levels are loaded on request: when you requests an entity that is not yet present in the context on the given level, the system requests the data from the context of the super level. The requesting continues up to the base level.

levelsAndContexts.png
This mechanism is used to separate data used by forms from the "real" data and merge them only when required.

  • To create an execution level, call the method com.whitestein.lsps.engine.state.xml.EvaluationLevelUtils.nextSublevel(String, ModelInstance).
  • To merge changes from a level into its super level, use the com.whitestein.lsps.engine.lang.EvaluationLevelMerger.mergeLevel(String).

    This method can merge for example changes from level 0:1:1 to level 0:1. When changes are merged to the base level, they become visible to the processes of the model instance in case of variables and non-shared records and they become visible to other model instances in the case of shared records. On merge to the parent level, the system checks for data conflicts: For example, if a variable is changed in the levels 0:1 and 0:2 and both levels are merged to their parent level 0, a conflict is detected. In the case of records, the conflict check is performed on each property: If the property P1 of a record R is changed in the level "0:1" and property P2 of the same record R is changed in the level "0:2" no conflict is detected during merge.

  • To clean changes in a level, call the method com.whitestein.lsps.engine.state.xml.EvaluationLevelUtils.cleanDataOfEvaluationLevel(ModelInstance, String) or com.whitestein.lsps.engine.state.xml.EvaluationLevelUtils.cleanDataOfLevelAndSublevels(ModelInstance, String).

    Note that the com.whitestein.lsps.engine.state.xml.EvaluationLevelUtils.cleanDataOfLevelAndSublevels(ModelInstance, String) method cleans changes in the level and in the child levels.

  • To remove a level, use the method com.whitestein.lsps.engine.state.xml.EvaluationLevelUtils.removeDataOfEvaluationLevel(ModelInstance, String) or com.whitestein.lsps.engine.state.xml.EvaluationLevelUtils.removeDataFromLevelAndSublevels(ModelInstance, String).
  • To check if there are changes in the non-base levels of a model instance, call com.whitestein.lsps.engine.state.xml.ModelInstance.isDirty(boolean).

Restrictions

  • A shared record instance created in a non-base level and not merged into the base level is not registered in the entity manager and hence not returned by queries.
  • Functions with side effects can cause changes in application state even if evaluated in a non-base evaluation level. Such functions are, for example, createModelInstance() and sendSignal().

Note: The GUI mechanism provided by the ui module makes use of execution levels:

  • Each form is created in the so-called screen level
  • Contexts of View Models are created on underlying levels referenced to as evaluation levels.