Corteza workflow (further referred to as a workflow) allow you to implement custom business logic without the need for any programming knowledge.
DevNote provide some diagrams regarding the packages and the flows.
The core workflow logic is implemented in the
Additionally, each main service provides its own
automation sub-package, which defines type definitions and handler function definitions.
automation package is responsible for CRUD operations over the resources that define the automation, such as the workflow and trigger.
In addition, it is responsible for setting up and manage the facility that prepares, executes and resumes workflows.
wfexec package is responsible for executing the provided automation over the provided context.
wfexec package unaware of the parent automation package and can execute any valid set of
wfexec.Step interfaces represented as a graph.
A workflow encapsulates the logic and the metadata for the automation. A workflow is not necessarily valid or executable.
A trigger encapsulates the logic and the metadata that define when the workflow should be executed.
A session encapsulates a workflow that is not not started (for example, started, suspended or completed). A session may be flushed to the database and restarted at a later point in time.
The automation registry contains type and handler definitions that the automation can use.
The graph encapsulates all of the steps defined for a specific workflow. The graph needs to traverse through the nodes and execute them in order.
The step is the graph node that executes the required operation.
The execution session encapsulates some internal execution logic, separate from the automation session.
The automation service setup initializes all of the sub-services, populates the automation registry, and prepares the facility to execute workflows and produce results.
initializes all of the sub-services, along with the automation registry,
registers all known workflows and triggers on the event bus,
initializes a session watcher, which will process execution requests.
When we register the workflow to the eventbus, its triggers are converted into a set of
eventbus.ConstraintMatcher interfaces; the workflow itself is converted into a
wfexec.Graph by the logic in the
The initial workflow validation (structure, relations) is performed when converting it to the
The core responsibility of the session watcher is to initialize
wfexec.Session structs on the root
context.Context when passed into the
Workflows are executed on the root
Workflow execution is either invoked via the eventbus or directly by a service.
matches all of the handlers that match the provided event,
invokes the workflow handler function (
automation/service/workflow.go@makeWorkflowHandler) to prepare the execution context,
creates and runs the automation session (
The automation session service creates the
automation.Session struct, which provides the core context of the execution, and wraps the
wfexec.Session, which provides the execution specific context.
wfexec.Session creation runs a
pkg/wfexec/session.go@worker), which executes the steps passed through the
automation.Session is executed, it executes the underlying
When a step is executed (
pkg/wfexec/session.go@.exec), the result is used to determine the next step to execute.
Handlers and types
Each service may define an
automation module that defines the data types and handler functions for that service.
Handlers are defined in the
automation/_handler.yaml files (for example
automation/log_handler.yaml) and are generated into
automation/.gen.go files (for example
The function step executes these handlers.
The generated files implement the boilerplate for the handler.
The main logic must still be implemented (for example
Types are defined in the
automation/expr_types.yaml files (for example
automation/automation/expr_types.yaml) and are generated into
automation/expr_types.gen.go files (for example
These types implement the
expr.TypedValue interface and can be used within expressions.
The generated files implement the boilerplate for the type. If the type requires additional complexity (such as gval selectors), you must implement those manually.
A workflow step may invoke itself or another workflow. This may cause the workflow to run indefinitely.
To counter this, we’ve implemented a run-time validation using a
callStack passed around through the
when a workflow is triggered, pull the current
callStackfrom the context,
callStacksize exceeds the configured limit, error out,
callStacksize does not exceed the configured limit, pass the