数据截至 (上游 commit 7cdd13a1beec)
最精妙处:control-flow-excluded 如何撑起分支、循环与竞速
30 秒导读: Rivet 是个纯数据流引擎——节点靠边相连,谁的输入齐了谁就跑(见 02 章)。可现实里的图需要
if、循环、短路、竞速这些控制流。Rivet 的绝招是:不额外建一张控制流图,而是发明一种特殊数据值control-flow-excluded(下称"排除值"),让它像毒药一样沿着边往下游传染。一个节点如果输入里带着这个"毒",它自己就"不执行"、并把毒继续传下去;只有极少数节点(if/ifElse/coalesce/graphOutput/raceInputs/loopController)能"解毒"。分支、循环、竞速全建立在这一个机制上。
1. 先建直觉:为什么数据流引擎需要"排除值"
1.1 数据流引擎的天生短板
先回顾上一章的心脏:GraphProcessor 是拉取式数据流——它不按顺序执行语句,而是看"哪个节点的输入都齐了",齐了就调度它跑。
这套模型天生没有 if。传统程序里 if (cond) { A } else { B } 意味着"要么执行 A,要么执行 B,不能都执行"。但在数据流图里,A 和 B 都是节点,它们的输入一旦齐了就都会跑——引擎不知道该"