FlowLink Engine
flowlink-engine is the execution side of FlowLink.
It owns:
- node registration
- plan execution entry
- runtime execution
- event emission
- ordered mailbox primitives
- workflow validation
- adapter contracts
- worker pull protocol DTOs and endpoint paths
It uses flowlink-core/ for shared protocol types. Plan ownership belongs to
flowlink-plan/planner/; engine packages validate workflow shape, own executable node/runtime
behavior, and execute plans.
The target execution path is:
flowlink-plan/planner builds a *core.Plan
- engine runtime runs that plan
Existing lower-level wrappers such as plan.Assembly.Build(workflow) or plan.Assembly.RunPlan(...)
are available for custom wiring, but the orchestration boundary belongs to flowlink-plan.
It does not own built-in default nodes or workflow source orchestration. Default nodes live in
flowlink-ext/; config loading, admin source, polling loader, planning entry, and worker helper
belong in flowlink-plan.
Business services should integrate FlowLink through flowlink-plan first. Lower-level packages
from this module remain available when custom execution wiring is needed, for example:
github.com/EthanScriptOn/FlowLink/flowlink-core
github.com/EthanScriptOn/FlowLink/flowlink-engine/node
业务运行入口归属 flowlink-plan。engine 不读取配置、不拉 workflow、不管理
admin source;业务代码推荐直接依赖 flowlink-plan。
Minimal pure-code shape through flowlink-plan:
assembly, err := plan.NewAssembly(nil)
if err != nil {
panic(err)
}
if err := assembly.RegisterNodeFunc("custom.echo", func(fc *core.FlowContext, node *core.NodeDefine) (interface{}, error) {
payload := map[string]interface{}{}
if envelope := fc.Envelope(); envelope != nil && envelope.Payload != nil {
payload = envelope.Payload
}
return map[string]interface{}{
"echo": payload,
}, nil
}); err != nil {
panic(err)
}
fc := core.NewFlowContext(context.Background()).SetEnvelope(envelope)
if err := plan.UseAssembly(fc, assembly); err != nil {
panic(err)
}
result, err := plan.ExecuteWorkflow(fc, workflow)
The control plane stays in flowlink-admin/, and the UI stays in flowlink-frontend/.
示例已经迁移到独立模块 flowlink-examples。
最小纯代码示例见 flowlink-examples/simpleworker/。
更接近真实业务 worker 的入口示例见 flowlink-examples/realworker/:它注册
业务节点,在启动期配置一次 FlowLink runtime,在每个请求中填充
core.FlowContext,并调用 plan.Execute(fc)。
flowlink-plan supports two startup styles:
- the host service maps its own config into
plan.Config and calls plan.ConfigureFromConfig
- FlowLink reads a
flowlink config section from a YAML file or env directory through plan.ConfigureFromFile
The request-side shape is intentionally small:
if err := plan.ConfigureFromFile(ctx, "configs"); err != nil {
return err
}
fc := core.NewFlowContext(ctx).
Params(map[string]interface{}{"text": "hello"})
result, err := plan.Execute(fc)
The config file shape is:
flowlink:
scope:
env: dev
workspace: default
workflow:
workflowId: wf_message_entry
version: v1
source:
type: admin
admin:
baseUrl: http://127.0.0.1:18080
token: ""
Directory mode follows the same environment convention as Switch: APP_ENV selects the env
subdirectory, and defaults to dev.
When flowlink.scope and flowlink.workflow are configured, request code only needs to put
business params into FlowContext. If a request sets a different scope or workflow reference,
FlowLink fails fast instead of silently running a different chain. Multi-workflow services can
omit flowlink.workflow and write workflowId/version into FlowContext, or call plan.ExecuteRef
explicitly.
Admin addresses are startup-level FlowLink config and should be supplied by plan.Config,
plan.ConfigureFromFile, or lower-level plan.RuntimeOptions.
If workflow tracing controls are bound to Switch names, initialize Switch SDK during service
startup and pass switchsdk.NewResolver() from flowlink-plan/switchsdk through
plan.RuntimeOptions.SwitchResolver or plan.Config.SwitchResolver. The plan layer resolves
those bindings before engine execution; engine still only sees ordinary tracing booleans. Switch
mode has no fallback value, so a missing resolver, empty name, missing rule, or resolution error
stops the workflow before it reaches engine runtime.
The same static entry also supports pure-code usage without admin: configure plan with an
Assembly, build your own Workflow, and call plan.ExecuteWorkflow(fc, workflow).
adapter-message helper 形态的示例见 flowlink-examples/publishedworker/。
新业务服务推荐优先使用上面的 ConfigureFromConfig 或 ConfigureFromFile 加
plan.Execute(fc) 入口。
If the published workflow is managed by flowlink-admin, business workers should use
flowlink-plan's plan.WorkerHTTPClient directly as the published workflow loader, or use
plan.PollingWorkflowLoader for a built-in polling manifest/cache layer. The control plane
exposes a lightweight pull protocol:
POST /worker/v1/workflow-bootstrap
POST /worker/v1/workflow-published
The intended pattern is simple polling: first pull the latest workflow heads for one service
scope, then load the full workflow JSON only when a workflowId/version changes.