Failure Classification#
本页是 Perago task attempt 结果状态的精确参考。它回答两个问题:某类失败会回写什么 Conductor status,以及失败结果是否会携带 workspace output。
Perago 的运行时结果只有三个状态:
状态 |
载荷形状 |
Conductor 语义 |
|---|---|---|
|
|
attempt 成功完成。workspace task 已发布 workspace output;workspace-free task 已返回业务 |
|
|
attempt 失败,但不是 Perago 判定的 terminal input-workspace 契约错误。 |
|
|
pre guardrail 失败,表示上游提供的 workspace input 不满足任务声明的输入文件契约。 |
RuntimeTaskResult 会拒绝不一致的载荷形状:完成状态必须有 output,失败状态必须有 reasonForIncompletion,失败状态不能携带 output。
Classification Rule#
result_for_exception(...) 目前只有一条特殊规则:
异常类型 |
Result status |
说明 |
|---|---|---|
|
|
task body 尚未运行,输入 workspace 未满足 task 的 pre guardrail。 |
其他异常 |
|
包括 bad input、Pydantic 校验失败、业务异常、post guardrail、attempt fence、publish fence 和 LakeFS 操作失败。 |
这意味着 FAILED_WITH_TERMINAL_ERROR 不是通用的“不可重试”桶。Perago MVP 只把 pre guardrail 放进这个状态;其他失败都保持普通 FAILED,由 Conductor 按生成 TaskDef 中的 retry policy 决定是否重试。
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 |
用户函数抛异常,或返回值不能通过 output Pydantic model 校验 |
|
否 |
post guardrails |
输出 workspace 文件形状不满足 task 的 post guardrail |
|
否 |
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 通过、两次 attempt fence 都通过、stage 成功且 publish 成功后才返回 COMPLETED。完成 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 |
用户函数抛异常 |
|
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 错误不会被包装成成功。
staging cleanup 和 local cleanup 的错误只写日志,不覆盖原始 task result。
merge timeout 或 result update 失败后,不应直接假设 publish 没发生;运维恢复需要检查目标 branch commit metadata。
MVP 不提供严格 exactly-once publication 证明。Reference 中的失败分类只描述 worker 如何回写当前 attempt result;跨 attempt 的恢复判断需要结合 perago.logical_task_key、perago.task_id、perago.staging_commit 等发布 metadata。