Workspace Transaction Model#

Perago 的 workspace transaction 是一个由 runtime 执行的 TCC-inspired 发布模型,只适用于需要发布 workspace 变更的可写路径。它把任务函数限制在 attempt-local workspace 内,让 worker runtime 负责 LakeFS staging、发布 fence、目标 branch 更新、Conductor result 和清理。

正式 LakeFS 操作步骤见 LakeFS 发布协议。本页说明该模型提供的保证以及不涵盖的范围。

设计目标#

Perago 的事务模型解决 workspace task attempt 的发布安全问题:

目标

Perago 的做法

任务函数保持简单

task body 只接收本机 Path 和 typed params,返回 typed result。

未确认写入不直接污染目标 branch

所有写入先进入 execution-scoped staging branch。

stale attempt 不应继续写 LakeFS

runtime 在可写路径的 stage 或 no-op branch relocation 前检查 attempt fence;stage 后、publish 前再检查一次。

retry 可以处理一个 abandoned publication

当 target head 是 input ref 的直接子提交时,runtime 使用 replacement publication。

read-only 节点不制造 workspace 历史

WorkspaceSpec(read_only=True) 不检查 HEAD、不 stage、不 publish,也不进入可写路径 attempt fence;output ref 保持 input ref,result 按普通 Conductor worker completion 回写。

可写 no-op 不制造 empty commit

diff 为空时不创建 staging branch;如果需要处理 abandoned publication,则将 target branch relocate 回 input ref。

不确定状态 fail closed

无法用 Conductor attempt 状态和 LakeFS HEAD 状态解释时,让当前 attempt 失败。

Perago 不把 workspace transaction 暴露成用户 API。任务作者不需要写 tryconfirmcancel 函数,也不需要在业务代码里直接操作 staging branch。

runtime 的 staged reference 必须完整携带 LakeFS repository、staging branch 和 staging commit。Cancel/cleanup、Confirm/publish 和 retry 判断都应由显式 staged reference 与 workspace input 驱动,不能依赖 worker-local mutable state 来补齐 repository identity。

TCC 映射#

Perago 借用 TCC 的阶段名称,但阶段由 runtime 完成:

阶段

Runtime 行为

成功产物

Try

对 diff 非空的可写 attempt,从 input workspace.ref 创建本次 execution 专属 staging branch,把本机 workspace 的 WorkspaceSpec.prefix 投影同步进去,并提交 staging commit。

staging commit。

Confirm

通过 attempt fence 和 publish fence 后,按协议 merge staging branch 或 hard-reset / relocate target branch 到 staged commit;可写 no-op 只做 HEAD 检查或必要的 branch relocate。

target branch 上的 published workspace ref,或 no-op 的 input ref。

Cancel

attempt 失败、stale 或完成后清理 staging branch 和本机 attempt-local workspace。

清理日志;不会回滚已成功 publish 的目标 branch。

其他事务模型的取舍:

模型

取舍

XA

Conductor task completion 与 LakeFS branch 更新不属于同一个 XA resource manager。

AT

Perago 没有透明代理业务写入,也没有可自动回滚 LakeFS commit 的 undo log。

Saga

Saga 要求业务补偿或恢复动作,和 Perago 让 task body 保持普通 typed Python 函数的目标冲突。

Attempt Fence#

Attempt fence 防止失效 worker 继续推进 workspace。Perago 在两个位置检查它:

  1. task body 和 post guardrails 成功之后、stage 之前。

  2. stage 成功之后、publish 之前。

fresh attempt 必须仍然匹配已 poll 到的 Conductor attempt:statusIN_PROGRESSworkflow_instance_idtask_idretry_count 都没有变化。任一条件失败,attempt 返回普通 FAILED,runtime 继续尝试清理 staging branch 和本机 workspace。

双 fence 的原因是 stage 本身可能耗时。第一次 fence 避免失效 attempt 上传 staging workspace,或在可写 no-op 路径回拨 target branch;第二次 fence 避免 stage 完成后已经失效的 attempt 继续更新目标 branch。

Publish Fence#

Publish fence 判断目标 branch 当前 head 是否仍可被本次 attempt 推进。MVP 接受两种状态:

目标 branch 状态

行为

current head 等于 input workspace.ref

diff 非空时 merge staging branch,允许首次发布;diff 为空时 no-op completion。

current head 的直接 parent 等于 input workspace.ref

视为 abandoned publication;diff 非空时使用 replacement publication,diff 为空时 relocate 回 input ref。

其他 branch advancement 都会触发 PublishFenceError。这通常表示目标 branch 被其他 workflow step、其他 workflow instance、人工写入或更复杂历史推进;runtime 不发布 workspace output,让 Conductor 按普通失败路径处理。

这个 publish fence 是 client-side soft fence。它在 publish 前读取和判断目标 branch head;它不提供 LakeFS server-side compare-and-swap,也不证明严格 exactly-once publication。

Metadata#

不需要任何 commit metadata。

commit message 可以用于人工排查。发布判断只看 Conductor attempt fence 和 HEAD 状态。

故障与恢复边界#

Perago 的 MVP 事务边界是 operationally bounded:

场景

行为

pre guardrail 失败

返回 FAILED_WITH_TERMINAL_ERROR,不运行 task body,不发布 workspace。

task body、post guardrail、download、stage 失败

返回普通 FAILED,不发布 workspace。

read-only task 成功

返回 COMPLETED,workspace output ref 保持 input ref,不检查 HEAD。

可写 no-op 成功

返回 COMPLETED,Perago 不会创建 empty commit,workspace output ref 保持 input ref。

attempt fence 失败

返回普通 FAILED,尝试清理 staging 和本机 workspace。

publish fence 或 publish 失败

返回普通 FAILED,不发布 workspace output。

cleanup 失败

保留原始 result,只写日志。

publish 已成功但 worker 死亡

不补发旧 completion;由 Conductor timeout/fail/retry,后续 execution 按 LakeFS HEAD 状态决定是否 replacement publish。

Fail closed 后,让 Conductor 按失败或重试策略推进;需要人工恢复时,从当前 target branch head 发起新的工作流。

运行时假设#

这个模型依赖以下运营约束:

  • workspace 写入 workflow 在定义上保持串行,不允许并行分支同时写同一个 LakeFS target branch。

  • 同一时间只有一个活跃 workflow instance 写入给定 workspace branch。

  • human、TS、Python 节点都必须遵守同一套 Conductor 权限边界。

  • runtime 必须具备执行 target branch merge 和 replacement publish 所需的 LakeFS 权限。

  • PublishBudget 应使用真实 LakeFS publish 观测值设置 timeout、heartbeat 和 shutdown grace。

更细的执行顺序见 Workspace Publication,LakeFS object 同步规则见 LakeFS Runtime