Files
orbit/docs/api/execution-history.md

9.7 KiB
Raw Blame History

执行尝试与证据查询 v1

更新:2026-09-17。四个只读接口及独立 Go SDK 已实现;对应 可运行示例 和 回归记录。

1. 用途与权限

任务代表一次受理的工作,尝试代表其中一次执行代次。领取后未获开始授权就过期的尝试也会保留,并消耗尝试预算。重连恢复同一次尝试,不创建新的尝试记录。

证据保存 Worker 的迟到、未开始或冲突报告。outcome=SUCCEEDED 只是原报告的声明;disposition=EVIDENCE_ONLY 表示采集时仅作为证据保存,不能解释为任务成功。权威任务状态与结果使用 GetTask 查询。当前只读接口不执行人工裁定、恢复或重试。平台自动重试保留每次失败结果;其规则及任务 effect_uncertain 见 安全重试。

四个接口均要求 Authorization: Bearer <token>、tasks:read 动作及任务所属队列范围。凭据确定命名空间,每次调用都重新校验有效性。ID 是 32 位小写十六进制字符串,全部父子关系都校验;知道尝试 ID 或证据 ID 不代表有权读取。

响应为 application/json,含 Cache-Control: no-store、X-Content-Type-Options: nosniff;追踪 ID 同时出现在 X-Request-ID 和正文 request_id。这些 JSON 供解析使用,不能直接嵌入 HTML。SDK 保留结果中的数字文本,不先转换为 float64。

2. 请求与分页

方法和路径 data 对象 SDK 方法
GET /v1/tasks/{task_id}/attempts AttemptPage ListTaskAttempts(ctx, taskID, page)
GET /v1/tasks/{task_id}/attempts/{attempt_id} Attempt GetTaskAttempt(ctx, taskID, attemptID)
GET /v1/tasks/{task_id}/attempts/{attempt_id}/evidence AttemptEvidencePage ListAttemptEvidence(ctx, taskID, attemptID, page)
GET /v1/tasks/{task_id}/attempts/{attempt_id}/evidence/{evidence_id} AttemptEvidence GetAttemptEvidence(ctx, taskID, attemptID, evidenceID)

没有请求体,不需要 Idempotency-Key。仅两个列表接受查询参数:

参数 类型 / 默认 限制
limit 整数,默认 20 1–100;SDK 的 0 表示不传、采用默认值,HTTP 显式 0 被拒绝
cursor 字符串,默认空 最长 1024 字节;原样使用前一页的 next_cursor,并进行 URL 编码

参数只能出现一次;未知字段、重复参数、错误 URL 编码、非法游标均返回 400。详情接口不接受查询参数。游标绑定命名空间、任务、尝试和列表类型,不能跨资源复用,也不能作为授权证明。

尝试按 epoch DESC,证据按 (created_at DESC, id DESC) 分页,相同微秒时间以 ID 区分。使用索引和位置条件,不使用 offset 或全量 count。items 始终为数组,空时为 [];没有下一页时省略 next_cursor。列表不带业务结果正文。

分页不承诺跨请求快照。读取期间尝试状态可能更新、可能出现新记录;刷新最新记录应从空游标重新读取。limit 可以调整,父资源不可改变。

curl --get "$ORBIT_URL/v1/tasks/$TASK_ID/attempts" \
  -H "Authorization: Bearer $ORBIT_TOKEN" --data-urlencode 'limit=20'
curl "$ORBIT_URL/v1/tasks/$TASK_ID/attempts/$ATTEMPT_ID" \
  -H "Authorization: Bearer $ORBIT_TOKEN"
curl --get "$ORBIT_URL/v1/tasks/$TASK_ID/attempts/$ATTEMPT_ID/evidence" \
  -H "Authorization: Bearer $ORBIT_TOKEN" \
  --data-urlencode 'limit=20' --data-urlencode "cursor=$CURSOR"
curl "$ORBIT_URL/v1/tasks/$TASK_ID/attempts/$ATTEMPT_ID/evidence/$EVIDENCE_ID" \
  -H "Authorization: Bearer $ORBIT_TOKEN"

变量使用实际资源 ID,首次证据查询的 CURSOR 设为空。成功均为 HTTP 200;响应信封见下方完整示例,ID 和时间为示意值。

3. 尝试字段与响应

字段 类型 / 是否始终返回 含义
id、task_id string / 是 尝试与父任务标识
epoch 十进制字符串 / 是 单任务执行代次;SDK uint64
concurrency_token 十进制字符串 / 否 有显式资源键时返回跨任务单调许可序号;SDK uint64,无键时为零并省略;历史查询不能授权执行,见 资源键契约
state string / 是 LEASED、RUNNING、SUCCEEDED、FAILED、CANCELLED、EXPIRED、UNKNOWN;枚举不表示全部状态转换已实现
revision 十进制字符串 / 是 记录版本,续租及归属变化可递增;SDK uint64
lease_until UTC RFC 3339 / 是 数据库记录的租约期限,查询不提供执行授权
authorized_at UTC RFC 3339 / 否 获批开始时间;省略表示尚未获批,不证明外部效果是否发生
ended_at UTC RFC 3339 / 否 尝试结束时间;尚未结束时省略
error_code string / 否 稳定错误分类,无错误时省略
retryable bool / 否 Worker 对明确失败的可安全重试声明,false 时省略;不证明平台实际安排了重试
created_at、updated_at UTC RFC 3339 / 是 创建和最近更新时间,最多微秒精度
session_id、worker_instance_id string / 仅详情 当前或最后归属会话及进程身份;会话可能因恢复改变,不是完整归属变更日志
result JSON / 仅详情,可省略 此尝试已保存的结果;无结果时省略,与追加证据分开

列表响应:

{
  "request_id":"44444444444444444444444444444444",
  "data":{"items":[{
    "id":"22222222222222222222222222222222",
    "task_id":"11111111111111111111111111111111",
    "epoch":"1","state":"SUCCEEDED","revision":"3",
    "lease_until":"2026-09-17T08:00:30Z",
    "authorized_at":"2026-09-17T08:00:01Z","ended_at":"2026-09-17T08:00:02Z",
    "created_at":"2026-09-17T08:00:00Z","updated_at":"2026-09-17T08:00:02Z"
  }]}
}

详情响应为展开对象:

{
  "request_id":"44444444444444444444444444444444",
  "data":{
    "id":"22222222222222222222222222222222",
    "task_id":"11111111111111111111111111111111",
    "epoch":"1","state":"SUCCEEDED","revision":"3",
    "lease_until":"2026-09-17T08:00:30Z",
    "authorized_at":"2026-09-17T08:00:01Z","ended_at":"2026-09-17T08:00:02Z",
    "created_at":"2026-09-17T08:00:00Z","updated_at":"2026-09-17T08:00:02Z",
    "session_id":"33333333333333333333333333333333",
    "worker_instance_id":"55555555555555555555555555555555",
    "result":{"version":"v1","sequence":9007199254740993}
  }
}

不返回 lease_secret、instance_secret、凭据或内部摘要。执行权限必须经过 Worker 开始/恢复与当前租约确认,不能通过历史详情推导。

4. 证据字段与响应

字段 类型 / 是否始终返回 含义
id、task_id、attempt_id string / 是 证据及已校验的父资源标识
outcome string / 是 原报告的 SUCCEEDED、FAILED 或 UNKNOWN
error_code string / 否 原报告的错误分类,空时省略
retryable bool / 否 原失败报告的重试声明,false 时省略;证据不触发执行
reason string / 是 LEASE_LOST(授权失效)、NOT_STARTED(未获批开始)、RESULT_CONFLICT(与已保存结果冲突)
disposition string / 是 固定 EVIDENCE_ONLY,描述采集处理方式
created_at UTC RFC 3339 / 是 首次保存时间,相同身份的重复报告不刷新
message_id string / 仅详情 原报告身份,便于追踪同一次重报
payload JSON / 仅详情 原报告结果或证据引用,最大 256 KiB,保留精确数字文本

列表响应:

{
  "request_id":"44444444444444444444444444444444",
  "data":{"items":[{
    "id":"66666666666666666666666666666666",
    "task_id":"11111111111111111111111111111111",
    "attempt_id":"22222222222222222222222222222222",
    "outcome":"SUCCEEDED","reason":"RESULT_CONFLICT","disposition":"EVIDENCE_ONLY",
    "created_at":"2026-09-17T08:00:03Z"
  }]}
}

详情响应:

{
  "request_id":"44444444444444444444444444444444",
  "data":{
    "id":"66666666666666666666666666666666",
    "task_id":"11111111111111111111111111111111",
    "attempt_id":"22222222222222222222222222222222",
    "outcome":"SUCCEEDED","reason":"RESULT_CONFLICT","disposition":"EVIDENCE_ONLY",
    "created_at":"2026-09-17T08:00:03Z",
    "message_id":"77777777777777777777777777777777","payload":{"version":"v2"}
  }
}

保存 v2 证据不会覆盖尝试中的 v1 结果。查询没有状态变更或去重写入;人工裁定、证据采纳与审计管理属于后续能力。

5. 错误、超时与兼容

HTTP / code 处理
400 INVALID_ARGUMENT 修正 ID、limit、游标及查询参数;不可盲目重试
401 UNAUTHENTICATED 核对凭据撤销/到期、应用及命名空间状态
403 PERMISSION_DENIED 凭据缺少 tasks:read
404 NOT_FOUND 资源不存在、父子不匹配、跨命名空间或不在队列范围内;不区分具体原因
503 UNAVAILABLE 只读查询失败,可在总体截止内有限退避重试
{"request_id":"44444444444444444444444444444444","error":{"code":"NOT_FOUND","message":"resource not found"}}

服务端操作期限 8 秒;SDK 默认 HTTP 超时 10 秒,可用 context 缩短。SDK 不自动重试查询;取消查询不取消任务。SDK 业务响应上限 1 MiB,列表通过省略大正文和最多 100 条保持有界。每次重读获得当次数据,不保证与前次完全相同。

当前开发契约为 v1,SDK 尚未发布版本,接入方式见 SDK 手册。SDK 忽略新增响应字段;已有字段含义改变需升级契约并回归。跨租户/队列、父子错配、重复证据、同时间戳分页、精确数字和大载荷均有实际回归,见 验证记录。