跳到主要内容

Step 的进阶保证

查看 Markdown

当 Step 并行运行、运行很久,或者使用 ASYNC durability 时,读这一页。Step 介绍每个 Step 都有的保证。

Dex 保存什么

简而言之:一个方法的写入会一起保存,但它们和其他 Step 及 RPC 之间没有隔离。

Dex 单独保存每次 WaitFor 或 Execute 调用。它把这次调用的 Attribute 写入和 Channel 发布与结果一起保存,而且只在方法成功时保存。对外部系统的调用不在这次保存里。

一个 Step 方法的修改会一次全部生效。但这挡不住其他 Step 和 RPC 同时修改同样的状态。方法读到的是 Dex 把它交给 Worker 时的 Flow 状态。在方法的修改生效之前,其他 Step 和 RPC 可能已经改了这些状态。Dex 不检查方法读到的值是否仍然是最新的。所以两个先读后写同一个 Attribute 的 Step 或 RPC,可能互相覆盖对方的更新。要避免这种情况,让它们都在这个 Attribute 上声明 lock。Dex 会让它们依次执行。见 Attribute lock。

失败和重新投递

简而言之:Dex 无法判断一个方法是否完成时,会再运行它,或者告诉你结果未知。

以下情况会让方法重复运行,或让它的结果未知。它们对每个 SDK 都成立:

  • Worker 在方法中途停止。 这次尝试失败,重试策略会再运行这个方法。它的外部调用可能已经发生。server 重启或故障转移时,Worker 手上的每次尝试都会这样。
  • heartbeat 只发送、不确认。 heartbeat checkpoint 可能丢失,所以重新运行可能从更早的 checkpoint 开始。
  • 被取消的方法会继续运行。 Dex 不会停止它的代码,它的外部调用仍然会生效。
  • ASYNC Step 可能重复一次尝试。 见 SYNC 和 ASYNC Step。
  • 重试用完时,结果可能未知。 recovery Step 会知道工作肯定没有运行(NOT_STARTED),或者可能运行过(NOT_COMPLETED)。遇到 NOT_COMPLETED 时,先用幂等键在目标系统里检查,再决定是否重复或报告这个效果。

SDK 参考中的 Failure and redelivery 给出每种情况的确切规则(英文):Python · Go · Java · TypeScript · Rust。

SYNC 和 ASYNC Step

Step 的 durability 决定 Dex 什么时候保存它的进度。

  • SYNC 是默认值。Dex 在 Worker 收到任务之前保存每次尝试的开始,在 Flow 继续之前保存结果。每一次都要等待写入对象存储。
  • ASYNC 在保存开始和结果之前,就把任务交给 Worker 并开始后续工作。Dex 把这些写入合并成大约 20 毫秒一批。单个 Flow 跑得更快。如果 Dex Server 节点在写入之前失败,Dex 会在新的状态快照上再运行同一次尝试,所以它可能读到不同的 Attribute 值。从丢失的结果开始的后续工作也会再运行。

需要最严格保证的效果选 SYNC。延迟重要、偶尔重新运行可以接受的短 Step 选 ASYNC。适合 ASYNC 的有:快速读取、内部记账,以及已经有幂等键保证可以安全重复的调用。付款、发邮件,或者任何在更新的快照上重新运行可能发出不同参数的调用,都保持 SYNC。StepOptions 设置单个 Step 的 durability,FlowConfig 设置整个 Flow 的。性能 给出两者的实测延迟。

取消、完成和顺序

取消一个 Step,会丢弃它当前方法还没有保存的一切:Attribute 写入、Channel 发布和它的决定。它的 WaitFor 已经保存的内容保留。一个决定或 RPC 永远不会取消它自己启动的 Step。被取消的 Step 已经消费的消息会怎样,见 Channel 的保证。

被取消方法的代码会一直运行到方法返回。方法应检查取消状态并返回。见 Step 取消。

GracefulComplete 结束它自己的分支,并请求 Dex 在没有 active Step 后完成 Flow。这个请求会一直有效:之后某个分支以 DeadEnd 结束,也不会撤回它。见完成请求。

即使所有 Step 都已结束,Flow 也会继续运行,直到有待处理的 GracefulComplete。RPC 仍然可以在里面启动新的 Step。用一个完成类的决定结束最后一个分支。如果 Flow 不能无限等待,就给它设置 Flow timeout。

Dex 大致按 Step 就绪的顺序启动它们,但不严格保证。不要依赖并行 Step 启动或结束的顺序。顺序重要时,用 Channel 或 Attribute lock。

下一步