Files
orbit/docs/api/task-source.md

132 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 任务直接来源查询
状态:P3已实现服务端、独立SDK及普通任务、计划、人工恢复示例。接口只读,使用已有模型和索引,不增加数据库外键或迁移。验证证据见[回归报告](../reports/phase-3-task-source.md)。
## 1. 请求与权限
`GET /v1/tasks/{task_id}/source`
请求头:`Authorization: Bearer <token>`。不需要请求体、Content-Type或Idempotency-Key,不接受任何查询参数。task_id为32位小写十六进制ID;认证决定命名空间,URL不能覆盖它。
权限为`tasks:read`及任务所属队列范围。每次请求验证当前凭据;不存在、跨命名空间或不在队列范围的任务均返回404。只获得来源引用,不因此获得计划定义、模板、管理或执行权限;读取完整计划及固定版本仍需`schedules:read`,见[计划手册](schedules.md)。
```sh
curl "$ORBIT_URL/v1/tasks/$TASK_ID/source" \
-H "Authorization: Bearer $ORBIT_TOKEN"
```
## 2. 响应字段
HTTP 200,使用`request_id`和`data`信封;X-Request-ID与正文一致。下表字段均位于data。
| 字段 | 类型 / 必填 | 含义 |
| --- | --- | --- |
| task_id | string / 是 | 已授权查询的任务ID |
| kind | string / 是 | DIRECT、MANUAL_RETRY或SCHEDULE |
| retry_of | string / 仅MANUAL_RETRY | 同命名空间、同队列的直接原任务ID |
| schedule | object / 仅SCHEDULE | 触发该任务的固定关联,字段如下 |
| schedule.schedule_id | string / 是 | 来源计划ID |
| schedule.schedule_version | 十进制字符串 / 是 | 实际触发时的非零uint64版本,发布新版本不改写它 |
| schedule.occurrence_id | string / 是 | 唯一关联该任务的触发记录ID |
| schedule.scheduled_at | UTC RFC3339 / 是 | 原计划时间,最多微秒精度,与实际受理/执行时间分开 |
| schedule.decision | string / 是 | FIRED单点触发或COALESCED合并触发 |
| schedule.covered_until | UTC RFC3339 / 仅COALESCED | 合并范围的排除上界,严格晚于scheduled_at |
DIRECT表示普通任务受理,包括单项和批量受理;任务内部的自动安全重试仍属于同一个任务,不改变来源。MANUAL_RETRY表示[人工重试](task-recovery.md)创建的新任务,只返回直接父任务,不递归遍历整条重试链。父任务继续保留原历史。
SCHEDULE中的版本来自触发记录,不能用计划最新版本替换。COALESCED对应区间`[scheduled_at, covered_until)`;合并范围内由计划定义确定原始时间点,不承诺每个自然时间单位都有一次触发。SKIPPED未创建任务,因此不会成为任务来源。
普通受理的完整响应:
```json
{
"request_id":"44444444444444444444444444444444",
"data":{
"task_id":"11111111111111111111111111111111",
"kind":"DIRECT"
}
}
```
人工重试的完整响应:
```json
{
"request_id":"44444444444444444444444444444444",
"data":{
"task_id":"11111111111111111111111111111111",
"kind":"MANUAL_RETRY",
"retry_of":"22222222222222222222222222222222"
}
}
```
计划合并触发的完整响应:
```json
{
"request_id":"44444444444444444444444444444444",
"data":{
"task_id":"11111111111111111111111111111111",
"kind":"SCHEDULE",
"schedule":{
"schedule_id":"22222222222222222222222222222222",
"schedule_version":"1",
"occurrence_id":"33333333333333333333333333333333",
"scheduled_at":"2026-09-17T00:00:00Z",
"decision":"COALESCED",
"covered_until":"2026-09-17T00:03:00.000001Z"
}
}
}
```
单点触发返回decision=FIRED并省略covered_until。所有不适用的可选字段省略,不用null占位。来源不包含任务payload/result、计划模板、策略、凭据或执行租约秘密。任务当前状态另用GetTask读取。
## 3. 关联校验与错误
平台采用无外键设计,本接口在认证事务内显式核对命名空间、任务、队列、计划、不可变版本与触发记录。人工重试父任务须为同队列中已失败/取消的独立任务。无所有者但存在触发记录、悬空父任务、缺失版本、错误队列、未知所有者或当前未支持的门控均拒绝,不能把关联损坏降级成DIRECT。
| HTTP / code | 处理 |
| --- | --- |
| 400 INVALID_ARGUMENT | 检查task_id;删除不受支持、重复或格式错误的查询参数 |
| 401 UNAUTHENTICATED | 检查凭据、过期、撤销及应用/命名空间状态 |
| 403 PERMISSION_DENIED | 需要tasks:read动作权限 |
| 404 NOT_FOUND | 任务不存在或不在当前命名空间/队列范围;旧版本节点也可能没有本路由 |
| 503 UNAVAILABLE | 数据库或来源关联不能可靠确认;不返回部分来源,不推测DIRECT |
读取不改变任务状态、版本、额度、尝试或审计。网络错误可以在有限预算内重新读取;SDK不自动重试。持续503应排查数据关联和服务日志,不能通过删除来源字段“修复”,也不能根据来源查询失败重新提交任务。
## 4. SDK调用与场景
```go
func (c *Client) GetTaskSource(ctx context.Context, taskID string) (TaskSource, error)
```
下方为已有客户端与taskID的调用片段;完整初始化、错误处理和可运行程序见后面的示例。
```go
source, err := client.GetTaskSource(ctx, taskID)
if err != nil { return err }
switch source.Kind {
case "DIRECT":
fmt.Println("普通受理", source.TaskID)
case "MANUAL_RETRY":
fmt.Println("直接原任务", *source.RetryOf)
case "SCHEDULE":
fmt.Println("来源计划", source.Schedule.ScheduleID,
"固定版本", source.Schedule.ScheduleVersion,
"触发记录", source.Schedule.OccurrenceID)
}
```
SDK的ScheduleVersion为uint64,JSON仍为字符串;时间使用time.Time。SDK验证响应task_id一致性、来源种类与字段组合、ID、版本及时间范围;未知kind或矛盾数据返回错误,不返回可误用的部分来源。协议新增来源种类时,接入方需升级SDK再使用。
| 场景 | 完整源码 | 运行说明与新增输出 |
| --- | --- | --- |
| 单项受理、取消后读取来源 | [tasks](../../sdk/go/examples/tasks/main.go) | [SDK初始化](../sdk/README.md),source_kind=DIRECT |
| 按计划找到触发任务,再反查来源 | [schedules](../../sdk/go/examples/schedules/main.go) | [计划场景](schedules.md#6-sdk-与完整示例),source_kind=SCHEDULE、fixed_version=1 |
| 人工核查后创建关联新任务 | [recovery](../../sdk/go/examples/recovery/main.go) | [恢复场景](../examples/recovery.md),source_kind=MANUAL_RETRY、parent=原任务ID |
上述示例均运行在隔离回归中;新发布计划版本后老任务仍指向旧版本,由真实数据库与SDK集成测试验证。Weave流程来源随P4–P5实现,目前没有WORKFLOW响应。此接口为新增只读路由,不更改Task/TaskSummary或Worker消息结构,不增加权限配置;新客户端调用旧节点的404不能理解为DIRECT。