Failure Classification#
本页提供 Perago task attempt 结果状态的精确参考,说明各类失败对应的 Conductor status,以及失败结果是否携带 workspace output。
Perago 的运行时结果只有三个状态:
状态 |
载荷结构 |
Conductor 语义 |
|---|---|---|
|
|
attempt 成功完成。workspace task 已生成 workspace output;workspace-free task 已返回业务 |
|
|
attempt 执行失败,Perago 认为同一 input 自动重试仍可能有意义。 |
|
|
attempt 执行失败,Perago 认为同一 input 自动重试没有意义。 |
RuntimeTaskResult 会拒绝不一致的载荷结构:完成状态必须有 output,失败状态必须有 reasonForIncompletion,失败状态不能携带 output。
Classification Rule#
运行时的内部异常 classifier 当前有这些规则:
异常类型 |
Result status |
说明 |
|---|---|---|
|
|
task body 尚未运行,输入 workspace 未满足 task 的 pre guardrail。 |
|
|
任务函数显式声明同一 input 自动重试没有意义。 |
|
|
任务函数显式声明该 attempt 失败,但同一 input 稍后重跑可能成功。 |
其他异常 |
|
包括 bad input、Pydantic 校验失败、未知业务异常、post guardrail、attempt fence、publish fence 和 LakeFS 操作失败。 |
任务作者应使用显式 failure API 表达业务执行失败:
raise TaskFailed("...")表示可自动恢复、值得重试的执行失败。raise TaskTerminalError("...")表示同一 input 自动重试没有意义的执行失败。未知、未处理的普通异常仍映射为
FAILED,让 Conductor 按 retry policy 处理。
业务可恢复但不应自动重试的情况不使用 Conductor failed 机制。业务函数应返回成功的 Result Output,例如 status="REJECTED" 或 status="NEEDS_ACTION",再由 WorkflowDef 的分支逻辑处理。
Workspace Task Attempt#
Workspace task 的 attempt 生命周期中,失败分类如下。
阶段 |
典型原因 |
Result status |
是否发布 workspace output |
|---|---|---|---|
input validation |
input 顶层字段缺少 |
|
否 |
download |
LakeFS repository/ref 不存在、连接失败、本机 workspace 写入失败 |
|
否 |
pre guardrails |
输入 workspace 缺少必需文件/目录/glob,或命中 forbidden glob |
|
否 |
task body retryable failure |
用户函数抛出普通异常、 |
|
否 |
task body terminal failure |
用户函数抛出 |
|
否 |
task body business branch |
用户函数成功判定业务无法继续自动执行,但 workflow 可处理该分支 |
|
视 workspace access mode 而定 |
post guardrails |
输出 workspace 文件未通过 task 的 post guardrail |
|
否 |
read-only completion |
|
|
否,output ref 保持 input ref |
no-op writable completion |
|
|
否,output ref 保持 input ref |
first attempt fence |
task body 后、stage 前发现 Conductor attempt 已不再是当前 attempt |
|
否 |
stage |
workspace 含 symlink、上传/删除/commit 失败 |
|
否 |
second attempt fence |
stage 后、publish 前发现 attempt 已失效 |
|
否 |
publish fence / merge |
target branch 被无关提交推进、merge 失败或 merge timeout |
|
否 |
staging cleanup |
staging branch 删除失败 |
保留原始 result |
保留原始 result |
local cleanup |
attempt-local workspace 删除失败 |
保留原始 result |
保留原始 result |
Workspace task 在 body 成功、post guardrail 通过后,按 workspace access mode 和 diff 决定完成路径。read_only=True 不进入 LakeFS HEAD 检查或 publication;read_only=False 且 diff 为空时 Perago 不会创建 empty commit,但必须通过 no-op HEAD 状态检查;read_only=False 且 diff 非空时必须完成 stage 和 publish。完成 output 会包含 workspace 和 result;失败 output 不会带 workspace,也不会把未发布的 attempt-local workspace 暴露给下游。
Workspace-Free Task Attempt#
Workspace-free task 不下载、不发布 workspace,也没有 guardrail 或 publish fence。
阶段 |
典型原因 |
Result status |
|---|---|---|
input validation |
input 顶层字段缺少 |
|
task body retryable failure |
用户函数抛出普通异常或 |
|
task body terminal failure |
用户函数抛出 |
|
task body business branch |
用户函数成功判定业务无法继续自动执行,但 workflow 可处理该分支 |
|
result validation |
返回值不能通过 output Pydantic model 校验 |
|
success |
业务函数返回值通过 output model 校验 |
|
Workspace-free task 的 COMPLETED output 只包含 result。它不会生成 workspace output,也不能通过 TaskControls.publish_budget 配置发布预算。
Conductor Result Payload#
Perago 内部先构造 RuntimeTaskResult,再转换成 Conductor SDK 的 TaskResult。
COMPLETED 会写入:
{
"status": "COMPLETED",
"output": {
"result": {
"valid": true
}
}
}
FAILED 会写入:
{
"status": "FAILED",
"reasonForIncompletion": "workspace task input must contain only workspace and params"
}
FAILED_WITH_TERMINAL_ERROR 会写入:
{
"status": "FAILED_WITH_TERMINAL_ERROR",
"reasonForIncompletion": "pre guardrail require_glob('raw/**/*.parquet') matched 0 files; min_count=1"
}
worker_id 不属于 RuntimeTaskResult payload。worker 向 Conductor 回写结果时会把 worker_id 写入 SDK TaskResult 字段,用于从 Conductor attempt 反查本机 worker 日志目录。
Recovery Boundary#
Perago 的失败分类是 fail-closed 的:
publish fence、stale attempt 和 LakeFS merge 错误不会被包装成成功。
业务可恢复分支不会被包装成 Conductor failure;它们应作为成功的
Result Output交给 workflow 分支处理。staging cleanup 和 local cleanup 的错误只写日志,不覆盖原始 task result。
publish timeout 或 result update 失败后,不应直接假设 publish 没发生;下一次 retry 按 LakeFS 发布协议 检查 target HEAD 状态。
MVP 不提供严格 exactly-once publication 证明。Reference 中的失败分类只描述 worker 如何回写当前 attempt result;跨 attempt 的发布判断来自 Conductor attempt fence 和 LakeFS HEAD 状态。