-
Notifications
You must be signed in to change notification settings - Fork 213
Persistence
IMPORTANT: This Kogito wiki is deprecated. For the latest Kogito documentation, see the Kogito documentation page. To contribute to Kogito documentation, see the
master-kogito
branch of thekie-docs
repository in GitHub.
Kogito supports (since version 0.3.0) a runtime persistence for workflows. That allows users to configure key value based storage backed by Infinispan to persist data (including active nodes and process instance variables) to preserve it across restarts.
Version of Infinispan currently used is 10.0.0.CR1
To enable it in the project there are two steps required
-
add maven dependencies
-
configure connection with Infinispan server
Note
|
as prerequisite Infinispan server must be installed and available over network |
Configuration will differ depending on selected runtime (Quarkus or SpringBoot)
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-infinispan-client</artifactId>
</dependency>
<dependency>
<groupId>org.kie.kogito</groupId>
<artifactId>infinispan-persistence-addon</artifactId>
<version>${kogito.version}</version>
</dependency>
<dependency>
<groupId>org.kie.kogito</groupId>
<artifactId>infinispan-persistence-addon</artifactId>
<version>${kogito.version}</version>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-spring-boot-starter-remote</artifactId>
<version>${infinispan-spring-boot.version}</version>
</dependency>
Add following into the src/main/resources/application.properties
file
infinispan.remote.server-list=127.0.0.1:11222
Note
|
Adjust the host and port number according to your Infinispan server installation. |
This is minimal configuration to make it work and obviously does not cover all possible aspects of configuration. Refer to Infinispan configuration options based on selected runtime to learn more.
Runtime persistence focuses mainly on storing data that are required to resume workflow execution for particular process instance. Regardless if the process is public or provide as long as it’s not completed it subject for persistence.
Node instances that are currently active, so called wait states, are persisted when process instance finished execution but have not reached end state (completed or aborted). This means that only information required to resume are persisted. There might be one or more active nodes instances stored at any given point in time.
All data that are included in the process instance are stored together with the process instance itself. These must be marshalled into a bytes format so it can be easily transferred over the wire and persisted into the key value storage. The marshalling and unmarshalling is implemented based on ProtoBuf and requires to have schema and marshallers available to know how to deal with given type of data.
Luckily Kogito comes with out of the box support to generate both marshallers and Protobuf schema (aka proto files). During build of the project, Kogito will scan all process definitions and extract information about data that are used within these business assets.
Next, based on the unique data types (regardless how many processes reference given type) a proto file (kogito-application.proto
) is generated that builds up a complete schema for the application. This file is stored in the target/classes/persistence/
folder after successful build.
syntax = "proto2";
package org.kie.kogito.examples;
import "kogito-types.proto";
message Order {
option java_package = "org.kie.kogito.examples.demo";
optional string orderNumber = 1;
optional bool shipped = 2;
optional double total = 3;
}
message Person {
option java_package = "org.kie.kogito.examples.demo";
optional bool adult = 1;
optional int32 age = 2;
optional string name = 3;
}
Note
|
Each kogito-application.proto file imports kogito-types.proto which defines base types automatically managed by Kogito.
|
Based on the kogito-application.proto
file, marshallers are also generated and configured in the application so whenever particular data type is used in process instance it can be successfully marshalled and unmarshalled.
Marshallers are based on the subproject of Infinispan called protostream.
Main rule is to try to stick to POJO/JavaBeans as data types that represent process variables. While doing that out of the box generation will provide most benefits. Diverging from it pose quite high probability of failed generation and by that failed build.
Currently following data types are supported:
Type | Description | Since version |
---|---|---|
java.lang.String |
Basic text type |
0.3.0 |
java.lang.Integer |
Basic number type |
0.3.0 |
java.lang.Long |
Extended size number type |
0.3.0 |
java.lang.Float |
Basic floating point number type |
0.3.0 |
java.lang.Double |
Extended size floating point number type |
0.3.0 |
java.util.Date |
Basic date type |
0.3.0 |
POJO/JavaBean |
POJO type that is build up from above simple types |
0.3.0 |
POJO/JavaBean with another POJO |
POJO type that is build up from above simple types and another POJOs |
0.3.0 |
POJO/JavaBean with list of POJOs |
POJO type that is build up from above simple types and another POJOs and List of POJOs |
0.3.0 |
Process instance is persisted as soon as it reaches a wait state, meaning it does not execute anymore but has not reached yet the final state (complete or abort). An example of such wait state is user task, or signal catch event. At this stage the complete snapshot of process instance is taken, that includes
-
process instance metadata such as id, proces id, state, description, start date etc.
-
active node instances including their variables
-
process instance variables
Process instance metadata is persisted with predefined protobuf schema that is aware of the metadata and support node instance that can be wait states.
Process instance and node instance variables are persisted based on the generated protobuf schema and generated marshallers. This allows to use custom data types within the process definition and ensure the data is properly persisted during execution.
In case of straight-through process instances, persistence is not even invoked as there is nothing to be stored since process instance has reached its final state.
Each process definition will have its own cache for storing runtime information. That is based on process id and as such will be named in the Infinispan server. Cache is automatically created if it does not exists. That kind of setup allows for easier maintenance of individual process instance data and reduces concurrency on the cache instances as well.