Flow 源码可视化
dexcli visualize 可以把一个 Go 或 Python Flow 源文件转换为静态 Flow Definition Graph。图中包含能够从源码确定的所有可能路径,而不是某一次 Flow 运行及其历史。
dexcli visualize ./order_flow.go
该命令会打开本地的 Flow Rendering 页面,并持续提供图形直到按下 Ctrl+C。需要 Flow Definition Graph 文件时使用 --json。未指定 --out 时,JSON 会写入标准输出;使用 --out 可以选择文件前缀:
dexcli visualize ./order_flow.py --json --out ./build/order-flow
使用 --json 可以把 JSON 写入标准输出:
dexcli visualize ./order_flow.py --json
在 Dex Web 中渲染定义图
启动 Dex 时指定包含生成后 JSON 文件的目录:
dexcli dev --flow-rendering-dir ./build
在 Dex Web 中打开 Flow Rendering。该页面独立于 Flow 搜索页和运行详情页,用于交互式渲染所选定义图。通过图例可以显示或隐藏控制流、WaitFor、RPC、Attribute、Channel、Stream、SubFlow 及诊断。Flow timeout handler 始终作为 Flow 的一部分显示。Stream 默认隐藏,其他图层默认显示。
Dex 会递归扫描 JSON 文件,并在启动时创建一次快照。文件改变后需要重启 Dex。无效 JSON、不支持的 schema 版本或非目录路径都会使启动失败并返回错误。
图中包含的内容
主 Flow 显示为浅紫色大框,每个 Step 是其中的浅蓝色中框。WaitFor 路径位于 Execute decision 上方。WaitFor 或 Execute 存在条件返回时,先经过一个棱形,再根据源码条件连接到不同卡片。
定义图包括:
- Flow 和起始 Step
- 已注册的 Step,以及按 Execute decision 分组的静态跳转
- 条件标签,以及固定数量或运行时数量的并行分支
- 有序的 WaitFor 条件,包括 Channel 数量、Timer 时长和外部 SubFlow
- RPC 和 timeout decision 及其后续 Step
- Attribute 名称、源码语言原生 value type 和 map 标记
- Channel、Attribute 和可选 Stream 的访问关系
- Execute 卡中的完成、失败、Channel-empty 检查和取消信息
- Execute 失败后的恢复路径
终止 decision 不再生成额外 terminal 节点。取消信息直接显示在 Execute 卡中,不再绘制重复箭头。起始 Step 使用 START 标记,不再生成合成的 start 边。Timer 作为 WaitFor 中的一行显示,不再生成独立节点。
错误返回或抛出的异常并不能确定另一个 Step,因此不会产生跳转。显式的 ProceedToOnExecuteFailure 或 on_execute_failure_proceed_to 策略会生成一条指向恢复 Step 的紫红色实线。恢复跳过 WaitFor 时,边的标签会明确说明。
资源箭头使用统一方向:
- publisher → Channel → consuming WaitFor
- Attribute writer → Attribute 框 → Attribute reader
- WaitFor → 折叠的 SubFlow
资源和 SubFlow 关系使用虚线,视觉上弱于 Step 之间的实线跳转。Channel 集中在 Flow 左上区域,Attribute 合并为一个框,RPC 六边形横跨 Flow 左边界。SubFlow 只显示为包含 Flow type 的紫色虚线小框,不展开内部 Step。
Renderer 默认会把完整 Flow 缩放到当前 viewport。Channel 和 Attribute 箭头默认隐藏;选择对应资源,或相关的 Step、WaitFor、Execute decision、RPC、timeout handler 后才会显示。默认视图因此优先呈现 control flow,同时仍能按需查看资源访问关系。
Attribute 关系包括读取、写入和加锁。Python analyzer 会追踪 Flow class 上的静态资源 alias,并记录 RPC 或 Step options 声明的 Attribute lock。
Stream 关系描述的是应用可观察输出,而不是控制流。Flow Rendering 默认隐藏 Stream,用户可以通过图例开启。JSON 会标记 Step Stream 写入可重复且为 best effort。Heartbeat 调用和 checkpoint 读取属于运行时可靠性细节,因此不会进入定义图。
支持的源码约束
首版要求每个源文件只包含一个 Flow。以下内容必须直接出现在该文件中:
- 静态 Step 注册
- 每个已注册 Step 的处理方法
- Dex 跳转和 WaitFor 定义
- RPC 的后续 Step
- Execute 失败后的恢复目标
- 持久化资源定义及其访问
- Step Stream progress 操作
可以使用普通业务辅助函数和导入的数据模型,但辅助函数不能隐藏 Dex 跳转、WaitFor 定义、资源定义或恢复目标。Step 类型、Flow 类型和资源名称必须能够静态确定。
Go 分析需要本地 Go toolchain,输入必须属于能够完成类型检查的 module 和 package。Python 分析要求 Python 3.11 或更高版本。Python analyzer 在隔离模式下使用标准库 AST,绝不会导入或执行应用模块。
对于 Python,analyzer 可以识别同步 Step generator 通过 yield 发出的 Stream output,也可以识别异步 Step handler 中同步入队的 Stream 写入。在 RPC 或 Flow timeout handler 中使用 Step Stream progress 属于无效代码,会产生阻断诊断。
首版不支持单文件中的多个 Flow、反射、动态 class、Dex 通配符导入、基于 getattr 的目标、monkeypatch,以及逃逸出处理方法的 movement 集合。TypeScript、Java、Rust 和递归多文件分析也不在首版范围内。
Unknown 节点和诊断
不支持的动态控制流不会被静默省略。输出会包含 Unknown 节点和错误诊断。默认 renderer 仍会显示部分图。使用 --json 时,命令会写出部分 JSON,并以状态码 1 退出。
warning 不会使图失效。例如,无法确定 value type 的 Attribute 会显示 unknown 并产生 warning。从起始 Step 或 RPC 都无法到达的已注册 Step 也会产生 warning。无效命令参数以状态码 2 退出。
存在任何阻断诊断时,JSON 中的 valid 字段为 false。消费方应阻止基于无效图的编辑或部署,但仍可使用其中已知的节点和边解释问题。
JSON 合约
Flow Definition Graph v1 schema 定义了源码位置、父子关系、结构化 WaitFor 和 decision 详情、资源类型、分支条件、边方向和诊断。该 schema 是未来可视化编辑器及其他语言 analyzer 的集成边界。
运行中 Flow 的操作命令请参阅 Dex CLI。