Workflow Protocol - State & History

Workflow 构建块内部机制的低层描述。

状态和历史管理

Dapr Workflows 采用事件溯源模式,这意味着工作流的状态是从一系列事件中推导出来的。本文档描述了 Dapr 如何存储和管理这些历史记录和状态。

后端存储:Dapr Actors

默认情况下,Dapr Workflow 引擎使用 Dapr Actors 作为其存储后端。每个工作流实例都映射到一个唯一的 actor 实例。这提供了以下特性:

  • 并发控制:Actors 确保在任意时刻只有一个操作在处理工作流实例。
  • 可靠性:Actor 状态会持久化到配置好的 Dapr 状态存储中。
  • 定时器:Dapr Actors 提供持久化提醒,用于实现工作流定时器。

工作流状态架构

工作流实例(actor)的状态由以下几个组件构成:

1. 元数据

存储有关该实例的高级信息:

  • instance_id:工作流的唯一 ID。
  • name:工作流的名称。
  • status:当前运行时状态(如 Running、Completed、Stalled 等)。
  • version:工作流版本的名称及任何活跃的补丁。
  • created_at:创建时间戳。
  • last_updated_at:最后活动时间戳。
  • input:原始输入数据。
  • output:最终输出数据(如已完成的)。

2. 历史记录

一系列 HistoryEvent 对象,记录工作流中发生的所有事件。为了优化大型历史记录,Dapr 通常将历史事件以分块或单独键值的形式存储在状态存储中:

  • 键格式wf-history-<instance_id>-<index>
  • 事件内容:序列化的 protobuf 消息,包含事件类型、时间戳以及类型特定的数据(如 TaskScheduledTaskCompleted)。

3. 收件箱(待处理事件)

已发生但尚未被编排器处理(重放)的事件集合。包括:

  • 向工作流引发的外部事件。
  • 已完成的 activity 结果。
  • 已触发的定时器。

当编排器下次运行时,它会"排空"收件箱,将这些事件移入历史记录,然后重放逻辑。

重放与状态重建

当 Worker(SDK)收到工作项时,Dapr 提供历史事件。SDK 通过按顺序重放这些事件来重建编排的内部状态(例如本地变量、当前执行点)。

确定性原则与历史记录

历史记录是"真相的来源"。如果编排代码以非确定性的方式发生变化(例如在现有代码中间添加新的 activity 调用),重放将失败,因为代码的请求将与记录的历史记录不匹配。

清除状态

当清除工作流时,Dapr 会从状态存储中删除元数据及所有相关的历史事件键。这通常是为了在完成工作流后进行清理。