exec

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 28, 2026 License: LGPL-3.0 Imports: 4 Imported by: 0

Documentation

Overview

Package exec holds the public node-execution contracts (ADR-012 v.1): the node executor a model element implements, the synchronizing-join variant, and the data-binding consumer/producer + Frame surface. The implementations (the instance's runtime environment, the data-plane Frame) live in internal/*; pkg/model depends only on these interfaces.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ActivationJoin

type ActivationJoin interface {
	NodeExecutor

	// Record registers arrivingTrackID's arrival on incomingFlowID and reports
	// whether the gateway has already fired — in which case the arrival is a trailing
	// token to be consumed (a discriminator / partial join ignores the arrivals after
	// the activating one). It makes no activation decision.
	Record(incomingFlowID, arrivingTrackID string) (firedAlready bool)

	// Recheck decides the join's fate using eval for data guards and fc for
	// reachability. Called only from the instance loop, so fc's live-token view is
	// consistent. Fires (Survivor + Merged), aborts (the rule is unsatisfiable), or
	// neither (wait).
	Recheck(eval GuardEval, fc FlowChecker) (Decision, error)
}

ActivationJoin is a converging gateway whose completion is an activation rule over per-triple data guards, arrival counts, and required gates (ADR-005 v.3 §2.11). It reuses the reachability machinery (FlowChecker) but, unlike a ReachabilityJoin, a token death makes it ABORT (the arrival count is monotonic, so a death can only make a triple unsatisfiable) rather than fire.

The arriving track only Records (reachability and guards are not read off the track goroutine — the live-token set the loop owns must not be raced); the loop owns the whole fire/abort decision via Recheck.

type Decision

type Decision struct {
	Survivor string
	Merged   []string
	Fired    bool
	Aborted  bool
}

Decision is the outcome of an ActivationJoin step: the gateway either fired (with a promoted survivor and the absorbed merged track ids), aborted (its activation rule can no longer be satisfied — the instance must fail), or neither (the arrival parks).

type FlowChecker

type FlowChecker interface {
	// CheckFlows returns the subset of flows still reachable for node — those
	// with a live token somewhere on a backward path from the flow's source to
	// the start. Reachability is structural (condition-ignoring) and
	// cycle-guarded.
	CheckFlows(node flow.Node, flows []*flow.SequenceFlow) ([]*flow.SequenceFlow, error)
}

FlowChecker answers reachability for a synchronizing join. It is implemented by the instance (which owns the static node graph and the live track positions) and is consulted only from the instance loop, so the live-token set it reads is consistent (ADR-005 v.2 §2.10, SRD-022 §6).

type Frame

type Frame interface {
	// InstantiateInputs creates the node's input instances in the frame.
	InstantiateInputs(defs []*data.Parameter) error

	// InstantiateOutputs creates the node's output instances in the frame.
	InstantiateOutputs(defs []*data.Parameter) error

	// LoadProperties creates the node's property instances in the frame.
	LoadProperties(defs []*data.Property) error

	// Inputs returns the node's instantiated input parameters.
	Inputs() []*data.Parameter

	// Outputs returns the node's instantiated output parameters.
	Outputs() []*data.Parameter

	// GetDataByID returns the data whose ItemDefinition id is id, resolving
	// frame-first then walking the container scopes.
	GetDataByID(id string) (data.Data, error)
}

Frame is the per-execution data-binding surface a node's LoadData/UploadData operate on. It is the narrow public view of the data-plane frame (the concrete implementation lives in internal/scope); a node sees only what it needs to instantiate and read its own data.

type GuardEval

type GuardEval func(cond data.FormalExpression) (bool, error)

GuardEval evaluates a Complex gateway's data guard against process-level data. It is supplied by the caller (the instance, built over its root data scope + the expression engine) so the gateway can test a triple's condition at a point — Activate / Recheck — that has no per-node execution frame. A nil cond is true (ADR-005 v.3 §2.11).

type NodeDataConsumer

type NodeDataConsumer interface {
	flow.Node

	// LoadData loads the node's data into the execution Frame.
	LoadData(context.Context, Frame) error
}

NodeDataConsumer is implemented by nodes that consume data: LoadData instantiates the node's inputs and properties in the execution Frame and fills the inputs from the node's incoming data associations. The track calls it before the node executes.

type NodeDataProducer

type NodeDataProducer interface {
	flow.Node

	// UploadData yields the node's outputs through the execution Frame.
	UploadData(context.Context, Frame) error
}

NodeDataProducer is implemented by nodes that produce data: UploadData fills the node's output instances in the execution Frame and pushes the outgoing data associations. The track calls it after a successful node execution, right before the Frame commit.

type NodeExecutor

type NodeExecutor interface {
	Exec(
		ctx context.Context,
		re renv.RuntimeEnvironment,
	) ([]*flow.SequenceFlow, error)
}

NodeExecutor runs a single node and returns its valid outgoing sequence flows on success or an error on failure.

type ReachabilityJoin

type ReachabilityJoin interface {
	SynchronizingJoin

	// Recheck re-prunes the join's now-unreachable incoming flows via fc and
	// reports completion without a new arrival. On completion it returns the
	// promoted survivor track id and the absorbed (merged) track ids.
	Recheck(fc FlowChecker) (complete bool, survivor string, merged []string)

	// IsTrailing reports whether arrivingTrackID reached the join after it had
	// already fired without being recorded — a late arrival (a reachability fire
	// can precede a branch that was deemed unreachable) that must be consumed, not
	// parked. Atomic, so the answer is consistent with this track's own Arrive.
	IsTrailing(arrivingTrackID string) bool
}

ReachabilityJoin is a SynchronizingJoin whose completion is non-local: it fires only when no live token can still reach an un-marked incoming flow. The owning loop supplies reachability through a FlowChecker and re-checks the join when a token parks at it and on every token death (ADR-005 v.2 §2.10).

type SynchronizingJoin

type SynchronizingJoin interface {
	NodeExecutor

	// Arrive records the arrival of a token on incomingFlowID from
	// arrivingTrackID, reporting whether the join is now complete and which
	// flow ids merged into this completion.
	Arrive(incomingFlowID, arrivingTrackID string) (complete bool, merged []string)
}

SynchronizingJoin is a NodeExecutor that also synchronizes multiple incoming flows before it executes (a converging parallel/inclusive gateway).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL