Effect 什么时候需要 workflow,什么时候不需要?
「下单、预留库存、等审批、扣款、发货」看起来就该上 workflow,但我的结论恰好相反:这类多步骤代码,绝大多数用不上。
只有当流程必须在进程重启、网络失败、延迟回调或人工等待之后继续,才需要 workflow;其余情况用 Effect.gen 加事务加补偿即可。 持久化执行是有成本的,Activity 的名字和顺序会变成历史的一部分,API 在源码里也仍标注为 unstable。
所以我用四个问题做门槛,下面逐个说。
一个请求里先查再写再通知,需要 workflow 吗?
不需要。这种代码整体失败了可以整体重试,进程中途丢了也没有业务损失,Effect.gen 配合事务和补偿就是合适的工具。把它做成 workflow,只是徒增 Schema 声明、稳定命名和引擎配置的负担。
四个问题怎么问?
全部为否就不要引入:
- 流程中途丢了进程,业务上是否不可接受?可以整体重试的,不需要。
- 是否存在以小时或天计的等待,或者要等外部回调、人工动作?
- 步骤是否有不可回滚的外部副作用,需要显式补偿?
- 同一个业务实体是否必须保证只有一条在途流程?
只命中最后一条怎么办?
只命中「同一个业务实体只能有一条在途流程」时,数据库唯一约束加幂等键往往就够了,不必引入 workflow。
如果前三条里有命中的,下一步是看 effect/workflow 怎么定义可恢复的流程,见Effect Workflow 怎么让长流程重启后接着跑?。
上了 workflow,要怎么对待流程的名字?
这是引入之后最容易踩的一个坑:Activity 的名字和顺序是流程历史的一部分,上线后要像数据库 schema 一样对待,不要随意重命名,也不要调换已发布步骤的顺序。它还会出现在 trace 里,名字要稳定且低基数,命名约定可以参考Effect 里怎么给函数加 span?。
源码里每个 Activity 执行时都会以 Activity 的名称创建 span,execute、poll、interrupt、resume 也有以 <WorkflowTag>.<操作> 命名的 span,并带上 executionId 属性。
版本是 effect 4.0.5。四个判断问题是我自己的取舍标准,不是官方给出的规则;span 命名的描述来自我读源码,没有另外起导出器验证。持久化恢复的行为是我用 SQLite 加两个进程验证过的,细节在上面链接的那篇里。