Documentation ¶
Index ¶
- Variables
- type Case
- type Config
- type Connection
- type Engine
- func (me *Engine) Close() error
- func (me *Engine) Current() (*Node, error)
- func (me *Engine) HasNext() bool
- func (me *Engine) HasPrevious() bool
- func (me *Engine) LoopNext() bool
- func (me *Engine) LoopPrevious(skipBackgroundNodes bool) bool
- func (me *Engine) Next() (bool, error)
- func (me *Engine) Previous(skipBackgroundNodes bool) (bool, error)
- func (me *Engine) Stack() []Stack
- func (me *Engine) State() []Step
- type Flow
- type InitImplFunc
- type JS
- type Looper
- type LooperCallback
- type Node
- type NodeDef
- type NodeIF
- type Position
- type Stack
- type Start
- type Step
- type Workflow
Constants ¶
This section is empty.
Variables ¶
var ( ErrWorkflowMissing = errors.New("cannot run without Workflow") ErrStartNodeMissing = errors.New("cannot run without the start node") ErrConditionDataMissing = errors.New("condition data missing") ErrConditionCaseConnection = errors.New("condition cases are not leading in any case to a node") ErrConditionConnectionsMissing = errors.New("condition connections missing") ErrNotExist = errors.New("does not exist") ErrConfigGetWorkflowMissing = errors.New("GetWorkflow missing in your config") ErrNodeImplementationNotProvided = errors.New("node impl not provided") )
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct { //GetWorkflow is your function that provides workflows for embedded use. GetWorkflow func(id string) (*Workflow, error) //State is provided by the workflow engine. If you pass it for a new instance you should get the same state as before. State []Step //GetData is used in the execution of the condition and it provides the data in the Execute function of the NodeIF. GetData func() interface{} //NodeImpl contains your implementations of the node types. The key of the map is the node type. NodeImpl map[string]*NodeDef }
* In this package there are a few words about internal, background and foreground nodes. The meaning of them is here explained. background node:
A background node is not blocking the process. When you call Next, you get a background node with Current if it is a node at the end of the workflow otherwise you will get a foreground node if no error occurred. In the background nodes implementation there should be always returned < proceed > true if no error occurred otherwise it is configured wrong. Which means Execute is called once if no error occurred. Background nodes can be skipped in the Previous call to be able to get back to the last foreground node if no error occurs. Please note, there is no detection for wrong configuration of background nodes during runtime. If your node implementation changes and has an effect on the execution type, you must keep the background flag consistent.
foreground node:
A foreground node is blocking the process. When you call Next usually you should get the foreground node by calling Current. Foreground nodes have states in the node implementation that causes Execute to be called more than once. For example a form node. It has at least two states. State one is presenting the form, state two or higher is validating the form.
internal node:
Currently there are just two internal nodes, which is workflow and condition. These nodes are handled by the engine itself, they are visible in the Stack but they can also be visible in Current. For example if the root workflow starts with another workflow or a condition.
type Connection ¶
type Connection struct { NodeID string `json:"id"` CaseValue interface{} `json:"value,omitempty"` }
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
* In this package there are a few words about internal, background and foreground nodes. The meaning of them is here explained. background node:
A background node is not blocking the process. When you call Next, you get a background node with Current if it is a node at the end of the workflow otherwise you will get a foreground node if no error occurred. In the background nodes implementation there should be always returned < proceed > true if no error occurred otherwise it is configured wrong. Which means Execute is called once if no error occurred. Background nodes can be skipped in the Previous call to be able to get back to the last foreground node if no error occurs. Please note, there is no detection for wrong configuration of background nodes during runtime. If your node implementation changes and has an effect on the execution type, you must keep the background flag consistent.
foreground node:
A foreground node is blocking the process. When you call Next usually you should get the foreground node by calling Current. Foreground nodes have states in the node implementation that causes Execute to be called more than once. For example a form node. It has at least two states. State one is presenting the form, state two or higher is validating the form.
internal node:
Currently there are just two internal nodes, which is workflow and condition. These nodes are handled by the engine itself, they are visible in the Stack but they can also be visible in Current. For example if the root workflow starts with another workflow or a condition.
func (*Engine) Current ¶
Current is providing the target node and the recent error. The target node can be an internal node or background node as well. It depends on the structure of the workflow. This call is thread safe.
func (*Engine) HasNext ¶
HasNext is providing the last state of being able to move forward. HasNext result is not guaranteed as the path can change during the execution with the provided data. This call is thread safe.
func (*Engine) HasPrevious ¶
HasPrevious is providing the last state of being able to move one step back. The result is guaranteed. This call is thread safe.
func (*Engine) LoopNext ¶
LoopNext is the same as Next but it combines hasNext and err into one bool so it can be used easier in a loop. To ensure if everything went well, you can just call Current() which provides the recent error This call is thread safe.
func (*Engine) LoopPrevious ¶
LoopPrevious is the same as Previous but it combines hasPrev and err into one bool, so it can be used easier in a loop. To ensure if everything went well, you can just call Current() which provides the recent error This call is thread safe.
func (*Engine) Next ¶
Next is moving one node further in the workflow The recent error can be retrieved by Current() as well. This call is thread safe.
func (*Engine) Previous ¶
Previous is moving one or more steps back. A step consists of background nodes and foreground nodes. By skipping background nodes it moves back to a foreground node if there is one otherwise it stops at the beginning. This call is thread safe.
func (*Engine) Stack ¶
Stack is providing a slice containing all the executed nodes no matter if it was during forward or backward. It contains internal nodes like workflow or condition. This call is thread safe.
type InitImplFunc ¶
type JS ¶
type JS struct {
// contains filtered or unexported fields
}
func NewJSParser ¶
func NewJSParser() *JS
type Looper ¶
type Looper struct {
// contains filtered or unexported fields
}
ensures entities are looped once to prevent from an endless loop in nested patterns
type LooperCallback ¶
type Node ¶
type Node struct { ID string `json:"id"` Name string `json:"name"` Type string `json:"type"` Detail string `json:"detail,omitempty"` Data compatability.CarriedStringMap `json:"data,omitempty"` Cases []*Case `json:"cases,omitempty"` Connections []*Connection `json:"conns,omitempty"` Position Position `json:"p"` // contains filtered or unexported fields }
func (*Node) HierarchyPath ¶
func (*Node) WFUniqueID ¶
type NodeDef ¶
type NodeDef struct { //Impl is an sample instance of the node impl. The purpose of this sample is only to get reflect.Type from your implementation. InitImplFunc func(n *Node) (impl NodeIF, err error) //Background true means it is a none blocking node. //Background false means the node has more than one inner state that will cause multiple executions. Background bool }
* In this package there are a few words about internal, background and foreground nodes. The meaning of them is here explained. background node:
A background node is not blocking the process. When you call Next, you get a background node with Current if it is a node at the end of the workflow otherwise you will get a foreground node if no error occurred. In the background nodes implementation there should be always returned < proceed > true if no error occurred otherwise it is configured wrong. Which means Execute is called once if no error occurred. Background nodes can be skipped in the Previous call to be able to get back to the last foreground node if no error occurs. Please note, there is no detection for wrong configuration of background nodes during runtime. If your node implementation changes and has an effect on the execution type, you must keep the background flag consistent.
foreground node:
A foreground node is blocking the process. When you call Next usually you should get the foreground node by calling Current. Foreground nodes have states in the node implementation that causes Execute to be called more than once. For example a form node. It has at least two states. State one is presenting the form, state two or higher is validating the form.
internal node:
Currently there are just two internal nodes, which is workflow and condition. These nodes are handled by the engine itself, they are visible in the Stack but they can also be visible in Current. For example if the root workflow starts with another workflow or a condition.
type NodeIF ¶
type NodeIF interface { //Execute is being called when the node becomes the current target, doesn't matter whether it goes forward or backward. //If the node was executed before and returned proceed = false, the same instance is being used again. Execute(node *Node) (proceed bool, err error) //Remove is being called when this node is not part of the path anymore. In other words, when it doesn't exist in the State Remove(node *Node) //Close will be called on the instance before the next node is being executed or when the end is reached //Close is always the last called method either Execute()* -> Close() OR Execute()* -> Remove() -> Close(). //Execute() can be called n times before Close() or Remove() as it is controlled by the node impl. //When it is called, the instance is released from the engine. Close() }