Documentation
¶
Overview ¶
Package exegraph provides an execution graph engine for running named steps with explicit dependencies and maximum parallelism.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsStepSkipped ¶
IsStepSkipped returns true if the error (or any error in its chain) is a StepSkippedError.
func Run ¶
func Run(ctx context.Context, g *Graph, opts RunOptions) (err error)
Run executes all steps in the graph respecting dependency order, with bounded concurrency. It returns nil if all steps succeed, or a combined error describing all failures.
The returned error may contain both genuine step failures and StepSkippedError values (for steps whose dependencies failed). Use RunWithResult when you need to distinguish failures from transitive skips via [RunResult.Steps].
Types ¶
type ErrorPolicy ¶
type ErrorPolicy int
ErrorPolicy controls how the scheduler handles step failures.
const ( // FailFast cancels all in-flight steps when the first step fails. FailFast ErrorPolicy = iota // ContinueOnError lets all independent steps run to completion and // aggregates errors at the end. Steps whose dependencies failed are skipped. ContinueOnError )
func (ErrorPolicy) String ¶
func (p ErrorPolicy) String() string
String returns the string representation of the ErrorPolicy.
type Graph ¶
type Graph struct {
// contains filtered or unexported fields
}
Graph holds a set of named steps with dependency edges. Steps are added via [AddStep] and the graph is validated via [Validate] before execution. Graph is not safe for concurrent use during construction; build it in a single goroutine, then pass it to Run.
func (*Graph) AddStep ¶
AddStep registers a step. Returns an error if the step is nil, the name is empty, the Action is nil, or a step with the same name already exists.
func (*Graph) Priority ¶
Priority returns the transitive dependent count for the given step. Steps with a higher count sit on wider critical paths and should be started first. The result is cached and computed once across all steps on first call.
type RunOptions ¶
type RunOptions struct {
// MaxConcurrency limits the number of steps running simultaneously.
// Zero (the default) caps at GOMAXPROCS×2; a positive value is honored
// as the upper bound (useful to bump or cap for IO-bound workloads).
// Negative values are treated as zero.
MaxConcurrency int
// ErrorPolicy determines behavior on step failure.
ErrorPolicy ErrorPolicy
// StepTimeout imposes a per-step deadline. When positive, each step's
// context is wrapped with context.WithTimeout before execution. If the
// step does not complete within the duration the context expires with
// context.DeadlineExceeded, which the scheduler treats as a normal step
// failure (respecting ErrorPolicy). Zero (the default) means no per-step
// timeout is applied.
StepTimeout time.Duration
// OnStepStart is called (if non-nil) when a step begins execution.
// It is invoked from worker goroutines and must be safe for concurrent use.
OnStepStart func(stepName string)
// OnStepDone is called (if non-nil) when a step finishes, with a nil error on success.
// It is invoked from worker goroutines and must be safe for concurrent use.
OnStepDone func(stepName string, err error)
}
RunOptions configures the execution graph scheduler.
type RunResult ¶
type RunResult struct {
// Steps contains timing for every step in execution order (by completion time).
Steps []StepTiming
// TotalDuration is the wall-clock time from the first step starting to the
// last step completing.
TotalDuration time.Duration
// Error is the combined error from all failed/skipped steps (same as Run returns).
Error error
}
RunResult captures the outcome of a graph execution including per-step timing.
func RunWithResult ¶
func RunWithResult(ctx context.Context, g *Graph, opts RunOptions) (result *RunResult)
RunWithResult executes all steps in the graph and returns a RunResult containing per-step timing, status, and aggregate error. This is the instrumented variant of Run for callers that need execution telemetry.
type Step ¶
type Step struct {
// Name uniquely identifies the step within a graph (e.g., "provision-networking").
Name string
// DependsOn lists the names of steps that must complete successfully before
// this step can start.
DependsOn []string
// Tags are optional labels for querying related steps (e.g., "provision", "deploy").
Tags []string
// Action is the function to execute when all dependencies are satisfied.
Action StepFunc
}
Step is a named unit of work with explicit dependencies on other steps.
type StepFunc ¶
StepFunc is the function a step executes. It receives a context that is canceled when the scheduler shuts down (FailFast policy) or the parent context is canceled.
type StepSkippedError ¶
type StepSkippedError struct {
StepName string
}
StepSkippedError indicates a step was not executed because one of its dependencies failed. Consumers can check for this with errors.As to distinguish "skipped due to dependency failure" from "step itself failed."
func (*StepSkippedError) Error ¶
func (e *StepSkippedError) Error() string
type StepStatus ¶
type StepStatus int
StepStatus represents the lifecycle state of a step during execution.
const ( StepPending StepStatus = iota // StepPending means the step has not yet started. StepRunning // StepRunning means the step is currently executing. StepDone // StepDone means the step completed successfully. StepFailed // StepFailed means the step completed with an error. StepSkipped // StepSkipped means the step was not executed (e.g. due to upstream failure). )
func (StepStatus) String ¶
func (s StepStatus) String() string
String returns the string representation of the StepStatus.