Documentation
¶
Index ¶
- Constants
- Variables
- func DeleteByPath(root map[string]any, path string) error
- func GetByPath(root map[string]any, path string) (any, bool)
- func MergeByPath(root map[string]any, path string, value any) error
- func SetByPath(root map[string]any, path string, value any) error
- type AsyncJob
- type AsyncJobQueue
- type AwaitTraceInfo
- type CheckpointOutputRebuilder
- type ClosureValidationIssue
- type ClosureValidationLevel
- type ClosureValidationMode
- type ClosureValidationResult
- type DirtyPlan
- type EdgeRuntimeState
- type Engine
- func (e *Engine) BuildDirtyPlan(runCtx *nodes.Context, wf workflow.Workflow, newInput map[string]any) (*DirtyPlan, error)
- func (e *Engine) BuildRunPlan(runCtx *nodes.Context, wf workflow.Workflow, newInput map[string]any) (*RunPlan, error)
- func (e *Engine) Close()
- func (e *Engine) CompleteAwaitNode(bindingID int64, eventPayload map[string]any, eventErr string, source string) RunResult
- func (e *Engine) CompleteNodeAndResume(taskID int64, nodeName string, meta map[string]any, errMsg string) RunResult
- func (e *Engine) CreateForkRun(ctx context.Context, sourceTaskID int64, userID int64, ...) (*domain.Task, error)
- func (e *Engine) GenTaskID() int64
- func (e *Engine) LoadForkParentSnapshot(runCtx *nodes.Context) error
- func (e *Engine) MaterializeRunPlan(runCtx *nodes.Context, wf workflow.Workflow, plan *RunPlan) error
- func (e *Engine) NodeRepo() repository.NodeRuntimeRepository
- func (e *Engine) PreviewRunPlan(ctx context.Context, sourceTask *domain.Task, resumeSpec *domain.ResumeSpec, ...) (*RunPlan, workflow.Workflow, error)
- func (e *Engine) ReconcileSubWorkflowBinding(bindingID int64) RunResult
- func (e *Engine) Replay(ctx context.Context, taskID int64) (*ReplayTrace, error)
- func (e *Engine) ReplayToWS(ctx context.Context, taskID int64, speedMs int) error
- func (e *Engine) ResumeTask(taskID int64, nodeName string, meta map[string]any) RunResult
- func (e *Engine) Run(ctx context.Context, task *domain.Task, def *definition.WorkflowDefinition) error
- func (e *Engine) RunSubWorkflow(execCtx *nodes.NodeExecContext, workflowName string, input map[string]any) (map[string]any, error)
- func (e *Engine) RunWithResult(ctx context.Context, task *domain.Task, def *definition.WorkflowDefinition) RunResult
- func (e *Engine) SetCostRecorder(recorder cost.Recorder)
- func (e *Engine) SetSubWorkflowBinding(enabled bool)
- func (e *Engine) TaskRepo() repository.TaskRepository
- func (e *Engine) ValidateResumeSpecForExternal(wf workflow.Workflow, resumeSpec *domain.ResumeSpec) error
- type EngineOption
- func WithAwaitBindingRepo(r repository.AwaitBindingRepository) EngineOption
- func WithBuilder(b *workflow.Builder) EngineOption
- func WithCostRecorder(r cost.Recorder) EngineOption
- func WithDistributedLock(l lock.DistributedLock) EngineOption
- func WithEventBus(b *eventbus.EventBus) EngineOption
- func WithEventRepo(r repository.EventRepository) EngineOption
- func WithJobQueue(q AsyncJobQueue) EngineOption
- func WithNodeRepo(r repository.NodeRuntimeRepository) EngineOption
- func WithSubWorkflowBinding(enabled bool) EngineOption
- func WithTaskRepo(r repository.TaskRepository) EngineOption
- func WithWorkflowRepo(r repository.WorkflowRepository) EngineOption
- func WithWorkflowVersionRepo(r repository.WorkflowVersionRepository) EngineOption
- type ExecutionReason
- type MapItemFrame
- type NodePlan
- type NodeReplayResult
- type NodeReplayService
- type NodeTraceFrame
- type ParentFanoutNodeKind
- type PlanAction
- type ReplayTrace
- type RetryTrigger
- type RunCancellationResult
- type RunCancellationService
- type RunPlan
- type RunPlanMode
- type RunRedoService
- type RunResult
- type RunStatus
- type TaskForkService
- type TaskRetryService
Constants ¶
const ( EditReplaceStartImage = "replace_start_image" EditReplaceEndImage = "replace_end_image" EditUserPrompt = "edit_user_prompt" )
const ( DirtyReasonInputChanged = "input_changed" DirtyReasonUpstreamDirty = "upstream_dirty" DirtyReasonMissingParent = "missing_parent_snapshot" DirtyReasonInputResolve = "input_resolve_failed" DirtyReasonParentNotReady = "parent_not_success" DirtyReasonPatchedState = "patched_state" DirtyReasonResumeBoundary = "resume_boundary" )
const AwaitUsageFactsMetaKey = "__usage_facts"
const CancelReasonSupersededByRevision = "superseded_by_revision"
const (
TaskNoRetryFound = "no retry root found task"
)
Variables ¶
var ( ErrRunCancellationTaskNotFound = errors.New("run cancellation: task not found") ErrRunCancellationNotAllowed = errors.New("run cancellation: task status cannot be canceled") )
var ErrNoJob = errors.New("async job queue: no job available")
ErrNoJob 表示当前没有可消费的异步任务(空轮询)。 队列实现(如 Redis Stream 的 block 超时)应返回该哨兵错误, 消费方据此静默重试,无需感知底层驱动的具体错误类型。
var ErrTaskCanceled = errors.New("task already canceled")
Functions ¶
Types ¶
type AsyncJobQueue ¶
type AwaitTraceInfo ¶
type AwaitTraceInfo struct {
AwaitType domain.AwaitType `json:"await_type"`
Source domain.AwaitSource `json:"source"`
Status domain.AwaitBindingStatus `json:"status"`
Provider *string `json:"provider,omitempty"`
ProviderTaskID *string `json:"provider_task_id,omitempty"`
ResultPayload map[string]any `json:"result_payload,omitempty"`
ErrorMessage string `json:"error_message,omitempty"`
PollAttempts int `json:"poll_attempts,omitempty"`
WaitingStartedAt *time.Time `json:"waiting_started_at,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
}
AwaitTraceInfo await 节点的挂起/回调详情
type ClosureValidationIssue ¶
type ClosureValidationIssue struct {
Level ClosureValidationLevel `json:"level"`
NodeName string `json:"node_name"`
EdgeKey string `json:"edge_key,omitempty"`
FieldName string `json:"field_name,omitempty"`
Message string `json:"message"`
}
ClosureValidationIssue describes a single state closure problem.
type ClosureValidationLevel ¶
type ClosureValidationLevel string
ClosureValidationLevel indicates severity.
const (
ClosureLevelBlock ClosureValidationLevel = "block"
)
type ClosureValidationMode ¶
type ClosureValidationMode string
ClosureValidationMode controls strictness per entry point.
const ( ClosureModeFork ClosureValidationMode = "fork" // strictest — no unstable or awaiting nodes ClosureModeResume ClosureValidationMode = "resume" // allow awaiting / suspended )
type ClosureValidationResult ¶
type ClosureValidationResult struct {
Valid bool `json:"valid"`
Issues []ClosureValidationIssue `json:"issues,omitempty"`
}
ClosureValidationResult aggregates all validation issues.
func ValidateParentStateClosure ¶
func ValidateParentStateClosure( parentNodes map[string]*domain.NodeRuntime, dag *graph.Graph, mode ClosureValidationMode, ) *ClosureValidationResult
ValidateParentStateClosure checks the parent task's node runtime states for DAG state closure consistency before fork/redo/resume operations.
type EdgeRuntimeState ¶
type EdgeRuntimeState string
EdgeRuntimeState 运行时边三态推导。 ActivatedEdges 持久化仍为 bool(不存三态),但所有调度判断统一通过 resolveEdgeState 从 edge.Type + parent.State + ActivatedEdges[key] 推导, 解决「false 同时表示条件未命中和必选父阻塞」的语义漏洞。
const ( // EdgeStateUnknown — 边状态尚未确定(父未 terminal 或 edge 未计算)。 EdgeStateUnknown EdgeRuntimeState = "unknown" // EdgeStateActive — 边被激活且父节点成功,参与下游 join。 EdgeStateActive EdgeRuntimeState = "active" // EdgeStateInactive — 条件边未命中(仅限父节点成功 + 条件不满足), // 该边从下游 join 剔除。 EdgeStateInactive EdgeRuntimeState = "inactive" // EdgeStateBlocked — 父节点 terminal 但非 Success(failed/skipped/canceled)。 // 无论 EdgeNormal 还是 EdgeCondition,父死即路径阻塞,不允许下游执行。 EdgeStateBlocked EdgeRuntimeState = "blocked" )
type Engine ¶
type Engine struct {
WorkflowVersionRepo repository.WorkflowVersionRepository
WorkflowRepo repository.WorkflowRepository
// contains filtered or unexported fields
}
Engine 工作流执行器
func New ¶
func New(opts ...EngineOption) *Engine
New creates an Engine from functional options.
The options-based constructor is the preferred way to create an Engine. The legacy NewEngine(a,b,c,...) positional constructor remains for backward compatibility.
func NewEngine ¶
func NewEngine( taskRepo repository.TaskRepository, nodeRepo repository.NodeRuntimeRepository, awaitBindingRepo repository.AwaitBindingRepository, workflowVersionRepo repository.WorkflowVersionRepository, workflowRepo repository.WorkflowRepository, builder *workflow.Builder, eventBus *eventbus.EventBus, jobQueue AsyncJobQueue, dLocker lock.DistributedLock, eventRepo repository.EventRepository, ) *Engine
func (*Engine) BuildDirtyPlan ¶
func (e *Engine) BuildDirtyPlan( runCtx *nodes.Context, wf workflow.Workflow, newInput map[string]any, ) (*DirtyPlan, error)
BuildDirtyPlan
规则: 1. parent snapshot success 全量 seed 到 planCtx 2. patch 应用到 planCtx 3. topo 顺序重新构造 input 4. 普通 hash 对比只决定“可否 reuse” 5. patched node 和 resume_from 再走优先级覆盖
func (*Engine) BuildRunPlan ¶
func (*Engine) Close ¶
func (e *Engine) Close()
Close 停止引擎的事件监听 goroutine 并等待其退出。 幂等;Close 之后引擎不应再执行任务。
func (*Engine) CompleteAwaitNode ¶
func (*Engine) CompleteNodeAndResume ¶
func (e *Engine) CompleteNodeAndResume( taskID int64, nodeName string, meta map[string]any, errMsg string, ) RunResult
CompleteNodeAndResume 外部事件唤醒挂起任务的统一入口: 用 meta 闭合 nodeName 节点(写输出、状态转 success-pending-edges),随后继续执行 DAG。
若该节点存在等待中的 await binding(await 节点挂起),走 CompleteAwaitNode 保证 binding 状态一并闭合;否则走 async 节点的抢占式闭合 + ResumeTask。 节点已被其他线程处理时返回 RunNoop,可安全重复调用。
func (*Engine) CreateForkRun ¶
func (*Engine) LoadForkParentSnapshot ¶
func (*Engine) MaterializeRunPlan ¶
func (*Engine) NodeRepo ¶
func (e *Engine) NodeRepo() repository.NodeRuntimeRepository
func (*Engine) PreviewRunPlan ¶
func (e *Engine) PreviewRunPlan( ctx context.Context, sourceTask *domain.Task, resumeSpec *domain.ResumeSpec, overrideInput map[string]any, ) (*RunPlan, workflow.Workflow, error)
PreviewRunPlan
用“源任务 + 临时 resumeSpec + overrideInput”构造一个纯内存 preview runCtx, 然后直接复用真实 BuildRunPlan 逻辑,返回可视化调试用的 RunPlan。 注意: 1. 不创建 task 2. 不写数据库 3. 不 materialize
func (*Engine) ReconcileSubWorkflowBinding ¶
ReconcileSubWorkflowBinding 是 subworkflow await binding 的 poll 对账兜底(P2)。
AwaitPollWorker 周期性对 due 的 subworkflow binding 调用本方法:直接查子任务的真实终态, 不依赖会丢的进程内事件,从而修复"子任务已完成但父任务没被唤醒"的静默挂起 (P1 把父节点落到 NodeAwaiting 退出了 heartbeat scanner,这条 poll 兜底就是它的安全网)。
与事件快路径(event_listen.go)汇聚到同一个 CompleteAwaitNode,靠 ClaimCompleting 原子去重, 两路只生效一次。子任务仍在执行时只重排下次对账;子任务终态失败/取消时把 binding 完成为失败, 父任务重试时由 RunSubWorkflow 的 TaskFailed/TaskCanceled 分支(Fix 4)负责复活,沿用既有语义。
func (*Engine) Replay ¶
Replay 基于已持久化的执行状态,对指定任务做纯读回放,不调用任何工具或写入任何数据。 返回结构化 trace,包含每个节点的解析后入参、输出、分支决策。
func (*Engine) ReplayToWS ¶
ReplayToWS 将已持久化的原始事件按 sequence 顺序重发到 task:{taskID} channel。 客户端订阅方式与真实任务完全一致,收到的事件类型也完全相同。 speedMs 控制事件间推送延迟(毫秒),0 表示无延迟。
func (*Engine) ResumeTask ¶
ResumeTask 恢复 Workflow 任务执行
func (*Engine) Run ¶
func (e *Engine) Run( ctx context.Context, task *domain.Task, def *definition.WorkflowDefinition, ) error
Run 执行 DAG,保留旧接口语义: 只有失败时返回 error,success/suspended/noop 都返回 nil。
func (*Engine) RunSubWorkflow ¶
func (*Engine) RunWithResult ¶
func (e *Engine) RunWithResult( ctx context.Context, task *domain.Task, def *definition.WorkflowDefinition, ) RunResult
RunWithResult 执行 DAG,并返回明确的运行结果状态。
func (*Engine) SetCostRecorder ¶
func (*Engine) SetSubWorkflowBinding ¶
SetSubWorkflowBinding 开启/关闭 subworkflow-as-await-binding 写入路径(P1,默认关闭)。
func (*Engine) TaskRepo ¶
func (e *Engine) TaskRepo() repository.TaskRepository
func (*Engine) ValidateResumeSpecForExternal ¶
type EngineOption ¶
type EngineOption func(*engineConfig)
EngineOption is a functional option for configuring an Engine.
func WithAwaitBindingRepo ¶
func WithAwaitBindingRepo(r repository.AwaitBindingRepository) EngineOption
WithAwaitBindingRepo enables await/signal nodes.
func WithBuilder ¶
func WithBuilder(b *workflow.Builder) EngineOption
WithBuilder is required — compiles WorkflowDefinition into executable Workflow.
func WithCostRecorder ¶
func WithCostRecorder(r cost.Recorder) EngineOption
WithCostRecorder sets a custom cost recorder (default: noop).
func WithDistributedLock ¶
func WithDistributedLock(l lock.DistributedLock) EngineOption
WithDistributedLock enables sub-workflow coordination across workers.
func WithEventBus ¶
func WithEventBus(b *eventbus.EventBus) EngineOption
WithEventBus is required — publishes task/node events.
func WithEventRepo ¶
func WithEventRepo(r repository.EventRepository) EngineOption
WithEventRepo is required — persists task events.
func WithJobQueue ¶
func WithJobQueue(q AsyncJobQueue) EngineOption
WithJobQueue is required — enables async node execution and sub-workflow scheduling.
func WithNodeRepo ¶
func WithNodeRepo(r repository.NodeRuntimeRepository) EngineOption
WithNodeRepo is required — stores and retrieves per-node runtime state.
func WithSubWorkflowBinding ¶ added in v1.0.3
func WithSubWorkflowBinding(enabled bool) EngineOption
func WithTaskRepo ¶
func WithTaskRepo(r repository.TaskRepository) EngineOption
WithTaskRepo is required — stores and retrieves task state.
func WithWorkflowRepo ¶
func WithWorkflowRepo(r repository.WorkflowRepository) EngineOption
WithWorkflowRepo is required — loads workflow metadata.
func WithWorkflowVersionRepo ¶
func WithWorkflowVersionRepo(r repository.WorkflowVersionRepository) EngineOption
WithWorkflowVersionRepo is required — loads workflow definitions from storage.
type ExecutionReason ¶
type ExecutionReason string
const ( ExecutionReasonNone ExecutionReason = "" ExecutionReasonReuseNode ExecutionReason = "reuse_node" ExecutionReasonPatchedNode ExecutionReason = "patched_node" ExecutionReasonResumeBoundary ExecutionReason = "resume_boundary" ExecutionReasonUpstreamDirty ExecutionReason = "upstream_dirty" ExecutionReasonInputChanged ExecutionReason = "input_changed" ExecutionReasonMissingParent ExecutionReason = "missing_parent_snapshot" ExecutionReasonParentNotReady ExecutionReason = "parent_not_success" ExecutionReasonInputResolveFail ExecutionReason = "input_resolve_failed" )
type MapItemFrame ¶
type MapItemFrame struct {
Index int `json:"index"`
Output map[string]any `json:"output"`
Reused bool `json:"reused"`
}
MapItemFrame map 节点逐 item 结果
type NodePlan ¶
type NodePlan struct {
Name string
Label string
NodeType definition.NodeType
Action PlanAction
Reason ExecutionReason
ReuseKind domain.ReuseKind
MapItemReuse map[int]bool
Patches []domain.RuntimePatch
// 调试 / 观测信息
ParentTaskID *int64
ParentNode *string
}
type NodeReplayResult ¶
type NodeReplayResult struct {
TaskID int64 `json:"task_id"`
NodeName string `json:"node_name"`
NodeState string `json:"node_state"`
NodeType string `json:"node_type"`
Tool string `json:"tool,omitempty"`
ResolvedInput map[string]any `json:"resolved_input,omitempty"`
OriginalOutput map[string]any `json:"original_output,omitempty"`
OriginalError string `json:"original_error,omitempty"`
ReplayOutput map[string]any `json:"replay_output,omitempty"`
ReplayError string `json:"replay_error,omitempty"`
Executed bool `json:"executed"`
}
type NodeReplayService ¶
type NodeReplayService interface {
ReplayTaskNode(ctx context.Context, taskID int64, nodeName string, execute bool) (*NodeReplayResult, error)
}
func NewNodeReplayService ¶
func NewNodeReplayService( taskRepo repository.TaskRepository, nodeRuntimeRepo repository.NodeRuntimeRepository, workflowVersionRepo repository.WorkflowVersionRepository, replayEngine *Engine, toolRegistry *tool.Registry, ) NodeReplayService
type NodeTraceFrame ¶
type NodeTraceFrame struct {
Name string `json:"name"`
Index int `json:"index"`
BizIndex int `json:"biz_index"`
State domain.NodeState `json:"state"`
StartedAt *time.Time `json:"started_at,omitempty"`
FinishedAt *time.Time `json:"finished_at,omitempty"`
DurationMs *int64 `json:"duration_ms,omitempty"`
ResolvedInput map[string]any `json:"resolved_input"`
Output map[string]any `json:"output"`
OutputPersisted bool `json:"output_persisted"`
ActivatedEdges map[string]bool `json:"activated_edges"`
ReuseKind domain.ReuseKind `json:"reuse_kind,omitempty"`
ReusedFromTaskID *int64 `json:"reused_from_task_id,omitempty"`
Error string `json:"error,omitempty"`
// Await 节点附加信息
AwaitInfo *AwaitTraceInfo `json:"await_info,omitempty"`
// Map/Loop 节点逐 item 结果
MapItems []MapItemFrame `json:"map_items,omitempty"`
}
NodeTraceFrame 单个节点的回放帧
type ParentFanoutNodeKind ¶
type ParentFanoutNodeKind string
const ( ParentFanoutNodeNone ParentFanoutNodeKind = "" ParentFanoutNodeMap ParentFanoutNodeKind = "map" ParentFanoutNodeLoop ParentFanoutNodeKind = "loop" )
type PlanAction ¶
type PlanAction string
const ( PlanActionReuse PlanAction = "reuse" // 直接复用父快照并注入 success PlanActionPatch PlanAction = "patch" // 复用父快照后打 patch,patched success PlanActionExecute PlanAction = "execute" // 进入 pending,等待 runDAG 真执行 )
type ReplayTrace ¶
type ReplayTrace struct {
TaskID int64 `json:"task_id"`
WorkflowVersionID int64 `json:"workflow_version_id"`
Status domain.TaskStatus `json:"status"`
StartedAt time.Time `json:"started_at"`
FinishedAt *time.Time `json:"finished_at,omitempty"`
Input map[string]any `json:"input"`
Nodes []NodeTraceFrame `json:"nodes"`
}
ReplayTrace 一次任务执行的完整回放结果
type RetryTrigger ¶
type RetryTrigger string
const ( RetryTriggerManual RetryTrigger = "manual" RetryTriggerRecovery RetryTrigger = "recovery_scanner" )
type RunCancellationResult ¶
type RunCancellationService ¶
type RunCancellationService interface {
CancelForSupersededRevision(ctx context.Context, taskID int64) (*RunCancellationResult, error)
}
func NewRunCancellationService ¶
func NewRunCancellationService( taskRepo repository.TaskRepository, nodeRepo repository.NodeRuntimeRepository, awaitBindingRepo repository.AwaitBindingRepository, ) RunCancellationService
type RunPlanMode ¶
type RunPlanMode string
const ( RunPlanModeInitial RunPlanMode = "initial" RunPlanModeFork RunPlanMode = "fork" )
type RunRedoService ¶
type TaskForkService ¶
type TaskForkService struct {
// contains filtered or unexported fields
}
func NewTaskForkService ¶
func NewTaskForkService( taskRepo repository.TaskRepository, workflowVersionRepo repository.WorkflowVersionRepository, builder *workflow.Builder, eng *Engine, ) *TaskForkService
type TaskRetryService ¶
type TaskRetryService interface {
PrepareTaskRetry(ctx context.Context, taskID int64, trigger RetryTrigger, resumeFrom string, patches []domain.RuntimePatch) error
ClearMapChildCheckpointResult(ctx context.Context, parentTaskID int64, nodeName string, childTaskID int64) error
}
func NewTaskRetryService ¶
func NewTaskRetryService( workflowVersionRepo repository.WorkflowVersionRepository, taskRepo repository.TaskRepository, nodeRuntimeRepo repository.NodeRuntimeRepository, awaitBindingRepo repository.AwaitBindingRepository, builder *workflow.Builder, ) TaskRetryService
Source Files
¶
- async_job.go
- await_complete.go
- checkpoint_rebuild_registry.go
- dirty_plan.go
- edge_state.go
- engine.go
- event_listen.go
- executor.go
- fork_reuse.go
- fork_snapshot.go
- helper.go
- job_queue.go
- node_replay.go
- options.go
- patch_checkpoint_rebuild.go
- patch_helper.go
- patch_path.go
- patch_plan.go
- patch_runtime.go
- patch_validation.go
- redo.go
- replay_engine.go
- resume.go
- run_cancellation.go
- run_context.go
- run_plan.go
- run_plan_builder.go
- run_plan_materializer.go
- run_plan_preview.go
- run_status.go
- state_closure.go
- subworkflow.go
- subworkflow_reconcile.go
- task_execution.go
- task_fork.go
- task_retry.go
- task_state.go
- usage_meta.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package redisjobqueue provides a Redis Stream backed engine.AsyncJobQueue.
|
Package redisjobqueue provides a Redis Stream backed engine.AsyncJobQueue. |