feat: add audited task review and linked manual retries
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
| `GET /health/ready` | 已实现,验证数据库、迁移记录及零外键要求 | [健康检查](health.md) |
|
||||
| `/v1/tasks` 提交、查询、分页与待执行取消 | P1 已实现 | [任务接口](tasks.md) |
|
||||
| `POST /v1/tasks:batch` | P3 已实现逐项受理、独立幂等、部分结果与补交 | [批量任务](batch-tasks.md) |
|
||||
| `/v1/tasks/{task_id}:review` / `:retry` 与 `/operations` | P3 已实现带证据核查、关联新任务与操作审计 | [人工恢复](task-recovery.md) |
|
||||
| `/v1/tasks/{task_id}/attempts` 与尝试详情 | P2 已实现 | [执行历史](execution-history.md) |
|
||||
| `/v1/tasks/{task_id}/attempts/{attempt_id}/evidence` 与证据详情 | P2 已实现 | [执行历史](execution-history.md) |
|
||||
| `/v1/queues` 创建、查询及 `:configure` 控制 | 已实现队列并发、开始速率、积压背压与暂停/恢复 | [队列接口与 SDK 场景](queues.md) |
|
||||
|
||||
@@ -58,4 +58,6 @@ P2 增加 workers:connect 和 workers:consume。bootstrap 只有显式提供 --w
|
||||
|
||||
P3 应用额度管理新增 `application:resources:read` 和 `application:resources:manage`。只有显式 `--resource-access` 才授予,作用域是所属应用的全部命名空间,普通队列管理不能替代。查询返回聚合计数,不开放其他命名空间的任务数据。`bootstrap --application-id <现有应用ID>` 可由数据库管理员增加命名空间,与 `--application` 二选一;验证应用启用及额度记录存在后,同事务创建新资源,所有秘密交付约定保持不变。应用默认未终结上限 1000000、并发 10000、开始速率 100000/秒;详见 [应用共享配额](application-resources.md)。
|
||||
|
||||
P3 独立任务核查、人工重试和操作审计分别增加 `tasks:review`、`tasks:retry`、`tasks:audit:read`,bootstrap显式 `--recovery-access` 才授予三项;默认凭据和 `--worker-access` 都不自动获得。核查/重试记录真实认证凭据及证据,读取任务详情仍需tasks:read,见[人工恢复](task-recovery.md)。
|
||||
|
||||
P3 结果订阅核心新增 `events:read`、`events:manage` 和 `events:consume`,bootstrap 仅显式 `--event-access` 时授予。订阅绑定创建凭据与单个队列,不能用同命名空间的另一张凭据消费或管理。当前 HTTP/WSS、管理及消费 SDK 已接入;凭据重绑继续开发,详见 [订阅接口](subscriptions.md)。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 安全重试 v1
|
||||
|
||||
状态:P3 的安全重试已实现。使用现有任务提交与 Worker 结果接口,无独立的自动重试路由;[Cron/固定间隔计划](schedules.md) 和 [运行中取消](cancellation.md) 已接入;[可靠结果订阅](subscriptions.md) 与业务Inbox已实现;独立任务人工核查与重试继续按 [计划](../08-development-plan.md) 开发。验证证据见 [本阶段报告](../reports/phase-3-safe-retry.md)。
|
||||
状态:P3 的安全重试已实现。使用现有任务提交与 Worker 结果接口,无独立的自动重试路由;[Cron/固定间隔计划](schedules.md) 和 [运行中取消](cancellation.md) 已接入;[可靠结果订阅](subscriptions.md) 与业务Inbox已实现;[独立任务人工核查与重试](task-recovery.md) 已实现,剩余能力继续按 [计划](../08-development-plan.md) 开发。验证证据见 [本阶段报告](../reports/phase-3-safe-retry.md)。
|
||||
|
||||
## 1. 三种不同的重报
|
||||
|
||||
@@ -31,7 +31,7 @@ Worker 的 `task.finish` 新增可选布尔字段 `retryable`,省略为 false
|
||||
|
||||
存在历史不确定效果时,只有 IDEMPOTENT 允许继续自动尝试。此声明要求跨进程、跨尝试、并发及迟到执行都具有业务幂等保障,例如持久化操作键、唯一约束、返回原结果及资源侧执行代次校验。Task.ID 在自动重试中稳定;AttemptID 会变化,不能作为跨尝试的业务幂等键。平台不会因为新尝试开始而保证旧进程已经停止。
|
||||
|
||||
`effect_uncertain` 是任务详情、摘要和派发任务中的可选布尔字段,false 时省略。只要曾发生尚未核实的授权执行,后来的明确失败、未开始即到期、总时限耗尽或取消都不会把该事实抹掉。当前有效尝试成功可自动清除;迟到成功证据不能清除。人工核查解除的管理接口尚未实现。
|
||||
`effect_uncertain` 是任务详情、摘要和派发任务中的可选布尔字段,false 时省略。只要曾发生尚未核实的授权执行,后来的明确失败、未开始即到期、总时限耗尽或取消都不会把该事实抹掉。当前有效尝试成功可自动清除;迟到成功证据不能清除。已实现[带证据核查](task-recovery.md):获授权管理主体确认历史执行结束及真实结果后,提交版本与结论;迟到证据本身不能代替核查。
|
||||
|
||||
## 3. 退避、预算与持久化
|
||||
|
||||
|
||||
232
docs/api/task-recovery.md
Normal file
232
docs/api/task-recovery.md
Normal file
@@ -0,0 +1,232 @@
|
||||
# 人工核查、人工重试与任务操作审计
|
||||
|
||||
状态:P3 已实现服务端、Go SDK 和[可运行场景](../examples/recovery.md)。与[自动安全重试](retries.md)不同,人工操作需要专门权限、原因、证据引用和当前版本。验证范围见[阶段报告](../reports/phase-3-task-recovery.md)。
|
||||
|
||||
## 1. 公共规则
|
||||
|
||||
- HTTPS `Authorization: Bearer <token>`,写入带 `Content-Type: application/json` 与稳定 `Idempotency-Key`;查询不带幂等键。
|
||||
- 权限分别是 `tasks:review`、`tasks:retry`、`tasks:audit:read`,均校验任务当前命名空间和队列范围。默认提交及 Worker 凭据不包含它们;开发初始化显式 `--recovery-access` 才添加。真实生产应分离执行与管理身份。
|
||||
- ID 为32位小写十六进制;`expected_revision` 是非零十进制字符串。正文最多512 KiB,拒绝未知字段、重复键、大小写别名及非允许的null。
|
||||
- 写操作幂等作用域:命名空间 + `task.review` / `task.retry` + 原任务ID + key。同键不同内容409;当前鉴权通过后优先返回原回执,不因任务已终结或额度已满重新执行。幂等保留约定与[任务受理](tasks.md)相同。
|
||||
- 网络/提交结果不明时持久保留**原键、原版本和完整正文**核对;不要换键。回执是操作当时快照,最新状态用 `GetTask`。SDK不自动生成身份或自动重试。
|
||||
- `reason`:非空白UTF-8,1–1024个Unicode字符,无NUL。`evidence_ref`:1–512个Unicode字符,无空白/控制字符;使用受控记录引用,禁止放入凭据秘密。平台只保存引用,不请求地址或自动判定证据真实性。
|
||||
|
||||
## 2. POST /v1/tasks/{task_id}:review
|
||||
|
||||
权限 `tasks:review`。仅 `NEEDS_REVIEW` 且版本匹配、无当前租约、无活跃尝试和未释放许可时允许。普通独立任务可核查;合法计划任务需同事务核验计划与触发记录归属。流程所属任务或有门控的任务拒绝,恢复须经对应上层控制器。
|
||||
|
||||
| 字段 | 类型/要求 | 含义 |
|
||||
| --- | --- | --- |
|
||||
| expected_revision | string,必填 | 当前待核查任务版本 |
|
||||
| reason / evidence_ref | string,必填 | 上述原因和证据边界 |
|
||||
| execution_settled | bool,必须显式true | 声明已核实全部历史执行已结束、不会继续产生效果 |
|
||||
| outcome | string,必填 | 仅SUCCEEDED或FAILED |
|
||||
| result | JSON,必填非null | 核查结论或业务结果引用,最多256 KiB,保留精确数值 |
|
||||
|
||||
先收集执行历史、迟到证据及外部系统凭证,核实所有旧执行和实际效果,再提交结论。仅“数据库租约已过期”不足以声明执行已经物理停止;平台无法杀死远程goroutine,也无法证明外部系统没有副作用。
|
||||
|
||||
请求示例,原状态为 NEEDS_REVIEW/revision=4:
|
||||
|
||||
```json
|
||||
{
|
||||
"expected_revision":"4",
|
||||
"reason":"已核实旧执行全部结束,操作未完成",
|
||||
"evidence_ref":"evidence:reconciliation-001",
|
||||
"execution_settled":true,
|
||||
"outcome":"FAILED",
|
||||
"result":{"confirmed":true,"sequence":9007199254740993}
|
||||
}
|
||||
```
|
||||
|
||||
首次及去重均返回HTTP200;完整示意响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"request_id": "44444444444444444444444444444444",
|
||||
"data": {
|
||||
"task": {
|
||||
"id": "22222222222222222222222222222222",
|
||||
"namespace_id": "33333333333333333333333333333333",
|
||||
"queue_id": "11111111111111111111111111111111",
|
||||
"state": "FAILED",
|
||||
"revision": "5",
|
||||
"handler": "object.prepare",
|
||||
"handler_version": "v1",
|
||||
"payload_version": "v1",
|
||||
"payload": {
|
||||
"object_ref": "objects/input",
|
||||
"sequence": 9007199254740993
|
||||
},
|
||||
"business_key": "object:operation-001",
|
||||
"available_at": "2026-09-17T00:00:00Z",
|
||||
"deadline_at": "2026-09-17T00:01:00Z",
|
||||
"recovery_safety": "RECONCILE_ONLY",
|
||||
"retry": {
|
||||
"max_attempts": 1,
|
||||
"initial_delay_ms": 0,
|
||||
"max_delay_ms": 0,
|
||||
"attempt_timeout_ms": 10000
|
||||
},
|
||||
"attempt_count": 1,
|
||||
"result": {
|
||||
"confirmed": true,
|
||||
"sequence": 9007199254740993
|
||||
},
|
||||
"completed_at": "2026-09-17T00:00:20Z",
|
||||
"created_at": "2026-09-17T00:00:00Z",
|
||||
"updated_at": "2026-09-17T00:00:20Z"
|
||||
},
|
||||
"audit_id": "55555555555555555555555555555555",
|
||||
"deduplicated": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
事务内保存新终态/result、清除effect_uncertain、revision加一、设置completed_at,释放一次未终结额度;同时保存幂等回执、不可变审计及新的结果事件。失败整体回滚,不能只更新状态后补写审计。旧尝试及UNKNOWN结果不改写,迟到报告仍只追加证据;已有needs_review结果事件保持冻结,订阅会再收到更高版本的最终结果。串行计划可以在核查终结后推进后续触发。
|
||||
|
||||
SDK:`ReviewTask(ctx, taskID, key, orbit.ReviewTaskRequest)` 返回 `ReviewTaskResult`。
|
||||
|
||||
## 3. POST /v1/tasks/{task_id}:retry
|
||||
|
||||
权限 `tasks:retry`。只接受**没有上层所有者的独立任务**,原状态FAILED或CANCELLED,effect_uncertain=false,版本匹配,无租约/活跃尝试/未释放许可。NEEDS_REVIEW先核查,SUCCEEDED不能重试;计划任务和流程任务均拒绝直接生成后继。
|
||||
|
||||
| 字段 | 类型/要求 | 含义 |
|
||||
| --- | --- | --- |
|
||||
| expected_revision | string,必填 | 原终态任务的当前版本 |
|
||||
| reason / evidence_ref | string,必填 | 重执行原因与安全依据 |
|
||||
| safe_to_retry | bool,必须显式true | 声明已确认旧执行结束,按原业务身份重新执行安全 |
|
||||
| task_timeout_ms | uint64,必填1–2592000000 | 新任务从受理起的总预算,最多30天;至少覆盖冻结的attempt_timeout_ms |
|
||||
| available_at | time/null,可选 | 新任务最早可执行时间,默认当前数据库时间 |
|
||||
| start_deadline_at | time/null,可选 | 新任务最晚开始时间,默认无独立限制,受新总截止时间约束 |
|
||||
|
||||
时间采用UTC RFC3339、微秒精度、年份2000–9998。available_at只允许最多1秒过去容差,必须早于新总截止;start_deadline_at必须晚于现在、不早于available_at、不晚于新总截止,详见[受理时间约束](tasks.md)。不继承原任务已经过期的绝对时间。
|
||||
|
||||
```json
|
||||
{
|
||||
"expected_revision":"5",
|
||||
"reason":"已核实旧执行不会继续产生效果,允许重新执行",
|
||||
"evidence_ref":"evidence:safe-retry-001",
|
||||
"safe_to_retry":true,
|
||||
"task_timeout_ms":60000
|
||||
}
|
||||
```
|
||||
|
||||
首次HTTP201,原键重报HTTP200且deduplicated=true。完整示意响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"request_id": "77777777777777777777777777777777",
|
||||
"data": {
|
||||
"source_task_id": "22222222222222222222222222222222",
|
||||
"task": {
|
||||
"id": "66666666666666666666666666666666",
|
||||
"namespace_id": "33333333333333333333333333333333",
|
||||
"queue_id": "11111111111111111111111111111111",
|
||||
"state": "WAITING",
|
||||
"revision": "1",
|
||||
"handler": "object.prepare",
|
||||
"handler_version": "v1",
|
||||
"payload_version": "v1",
|
||||
"payload": {
|
||||
"object_ref": "objects/input",
|
||||
"sequence": 9007199254740993
|
||||
},
|
||||
"business_key": "object:operation-001",
|
||||
"available_at": "2026-09-17T00:00:30Z",
|
||||
"deadline_at": "2026-09-17T00:01:30Z",
|
||||
"recovery_safety": "RECONCILE_ONLY",
|
||||
"retry": {
|
||||
"max_attempts": 1,
|
||||
"initial_delay_ms": 0,
|
||||
"max_delay_ms": 0,
|
||||
"attempt_timeout_ms": 10000
|
||||
},
|
||||
"attempt_count": 0,
|
||||
"created_at": "2026-09-17T00:00:30Z",
|
||||
"updated_at": "2026-09-17T00:00:30Z",
|
||||
"retry_of": "22222222222222222222222222222222"
|
||||
},
|
||||
"audit_id": "88888888888888888888888888888888",
|
||||
"deduplicated": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
新任务保留原队列、处理器与输入版本、payload、business_key、concurrency_key、priority、recovery_safety和冻结重试策略;新ID、revision=1、attempt_count=0和新时间预算,`retry_of`指回原任务。原任务终态、版本、结果和尝试次数均保持不变。
|
||||
|
||||
每个原任务最多一个直接重试后继;不同键竞争时只有一个成功,其余409,继续人工重试应沿失败/取消的后继任务操作。同键重报返回同一子任务和audit_id。唯一索引 `(namespace_id,retry_of)` 兜底,关联存在与归属由事务校验,**无数据库外键**。
|
||||
|
||||
新任务占用原队列与应用额度,仍受背压/暂停/并发/限速/资源键控制;满额不创建子任务、不遗留幂等身份。人工声明不能替代业务幂等:业务操作身份仍须保持稳定,新taskID不能直接用作外部业务的去重身份。
|
||||
|
||||
`task.retry`审计记在原任务上,after包含retry_task_id;子任务的task.accepted事件包含retry_of和audit_id。任务详情、单项回执和Worker分配中的retry_of为新增可选字段;任务摘要列表没有该字段。
|
||||
|
||||
SDK:`RetryTask(ctx, taskID, key, orbit.RetryTaskRequest)` 返回 `RetryTaskResult`。
|
||||
|
||||
## 4. 查询不可变操作审计
|
||||
|
||||
权限 `tasks:audit:read`,与普通tasks:read分开;当前凭据与队列范围逐次校验,不返回其他任务的审计或秘密。
|
||||
|
||||
`GET /v1/tasks/{task_id}/operations?limit=20&cursor=...`:limit默认20,1–100,cursor最长1024;参数只能出现一次且不能传未知筛选。按(created_at DESC,id DESC)分页;游标绑定命名空间、任务和查询种类。不是跨页快照,新的并发操作需从首页重新查询。
|
||||
|
||||
```json
|
||||
{
|
||||
"request_id":"44444444444444444444444444444444",
|
||||
"data":{
|
||||
"items":[{
|
||||
"id":"88888888888888888888888888888888",
|
||||
"task_id":"22222222222222222222222222222222",
|
||||
"operation_id":"99999999999999999999999999999999",
|
||||
"actor_id":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"action":"task.retry",
|
||||
"created_at":"2026-09-17T00:00:30Z"
|
||||
}],
|
||||
"next_cursor":"<服务端返回的不透明游标>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`GET /v1/tasks/{task_id}/operations/{audit_id}`:200详情在上述摘要基础上增加reason、可选evidence_ref、before和after;不存在或不属该任务返回404。
|
||||
|
||||
```json
|
||||
{
|
||||
"request_id":"44444444444444444444444444444444",
|
||||
"data":{
|
||||
"id":"88888888888888888888888888888888",
|
||||
"task_id":"22222222222222222222222222222222",
|
||||
"operation_id":"99999999999999999999999999999999",
|
||||
"actor_id":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"action":"task.retry",
|
||||
"created_at":"2026-09-17T00:00:30Z",
|
||||
"reason":"已核实旧执行不会继续产生效果,允许重新执行",
|
||||
"evidence_ref":"evidence:safe-retry-001",
|
||||
"before":{"state":"FAILED","revision":"5"},
|
||||
"after":{
|
||||
"source_task_id":"22222222222222222222222222222222",
|
||||
"retry_task_id":"66666666666666666666666666666666",
|
||||
"safe_to_retry":true,
|
||||
"task_timeout_ms":60000
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
核查after包含state、revision、effect_uncertain=false、execution_settled=true及result_digest。摘要不复制完整业务输入;详情也不返回租约/凭据秘密。核查/重试的actor_id由实际认证凭据确定,不能在正文自报。审计可含受理、取消、执行结果等其他动作;查询操作记录不等于获得任务执行权。
|
||||
|
||||
SDK:`ListTaskOperations(ctx, taskID, HistoryPageRequest)`、`GetTaskOperation(ctx, taskID, auditID)`。
|
||||
|
||||
## 5. 错误与兼容
|
||||
|
||||
| HTTP/错误码 | 处理 |
|
||||
| --- | --- |
|
||||
| 400 INVALID_ARGUMENT | 修正字段、显式确认、预算、JSON或游标,不触及任务 |
|
||||
| 401 UNAUTHENTICATED | 核对凭据到期/撤销与所属应用启用情况 |
|
||||
| 403 PERMISSION_DENIED | 当前凭据未获该管理/审计权限 |
|
||||
| 404 NOT_FOUND | 任务/操作不存在,或命名空间/队列/任务归属不匹配 |
|
||||
| 409 STATE_CONFLICT | 状态/版本/所有者/门控不允许,或已有直接重试后继;先读当前状态和审计 |
|
||||
| 409 IDEMPOTENCY_CONFLICT | 同操作身份正文变化,核对已保存原请求 |
|
||||
| 429 QUEUE_FULL / APPLICATION_FULL | 新任务受理背压,释放额度后原请求重试;错误携带retry_after_ms提示 |
|
||||
| 503 UNAVAILABLE 或网络错误 | 操作可能已提交,保持原身份核对 |
|
||||
|
||||
完整通用错误边界与请求大小限制见[任务接口](tasks.md)。新接口调用旧服务返回404,不静默改成重新SubmitTask。旧SDK忽略retry_of响应字段;使用additionalProperties=false的旧版严格Schema验证器需更新Schema。需要恢复接口与关联追踪时升级当前SDK。Worker协议仍为v1,retry_of是可选新增字段。
|
||||
|
||||
迁移000015不新增模型字段:明确中文retry_of语义,将相同列的历史非唯一索引替换为唯一索引,并增加禁止自关联CHECK。停止旧写入节点后迁移并统一升级;迁移遇到历史非法重复或自关联应失败,不能自动删除数据。跨版本混合负载和生产滚动发布尚未验收。
|
||||
@@ -92,7 +92,7 @@ curl -i "$ORBIT_URL/v1/tasks" \
|
||||
}
|
||||
```
|
||||
|
||||
可选响应字段:start_deadline_at、result、cancel_requested_at、completed_at、business_key、concurrency_key,未设置时省略。effect_uncertain=true 表示存在尚未核实的授权执行效果,false 时省略;详情、摘要和 Worker 派发均可返回。等待重试时 result/completed_at 省略,历史结果在尝试中保留。终态有 completed_at。状态集合为 WAITING / LEASED / RUNNING / NEEDS_REVIEW / SUCCEEDED / FAILED / CANCELLED;P1 仅主动产生 WAITING 和 CANCELLED。
|
||||
可选响应字段:start_deadline_at、result、cancel_requested_at、completed_at、business_key、concurrency_key、retry_of,未设置时省略。effect_uncertain=true 表示存在尚未核实的授权执行效果,false 时省略;详情、摘要和 Worker 派发均可返回。retry_of仅在任务详情、受理回执和Worker派发中标识人工重试的原任务,列表摘要不包含。等待重试时 result/completed_at 省略,历史结果在尝试中保留。终态有 completed_at。状态集合为 WAITING / LEASED / RUNNING / NEEDS_REVIEW / SUCCEEDED / FAILED / CANCELLED;P1 仅主动产生 WAITING 和 CANCELLED。
|
||||
|
||||
### 幂等与失败处理
|
||||
|
||||
@@ -190,4 +190,4 @@ SDK:`Client.CancelTask(ctx, taskID, key, request)`。此操作不承诺回滚
|
||||
{"request_id":"44444444444444444444444444444444","error":{"code":"IDEMPOTENCY_CONFLICT","message":"idempotency key was used with different content"}}
|
||||
```
|
||||
|
||||
有限自动重试已实现,具体分类、退避、回执和升级边界见 [安全重试](retries.md)。[运行中取消](cancellation.md) 已实现;[批量受理](batch-tasks.md) 已实现逐项结果与原身份补交;独立任务人工重试仍待实现。[执行历史](execution-history.md) 已提供尝试与证据的列表和详情。完整可运行程序见 [SDK 任务示例](../../sdk/go/examples/tasks/main.go),已验证异常场景见 [P1 回归报告](../reports/phase-1.md) 及 [取消回归](../reports/phase-3-cancellation.md)。SDK 忽略未知响应字段;更改已有字段语义需升级契约和回归。
|
||||
有限自动重试已实现,具体分类、退避、回执和升级边界见 [安全重试](retries.md)。[运行中取消](cancellation.md) 已实现;[批量受理](batch-tasks.md) 已实现逐项结果与原身份补交;[独立任务核查与关联新任务重试](task-recovery.md) 已实现。[执行历史](execution-history.md) 已提供尝试与证据的列表和详情。完整可运行程序见 [SDK 任务示例](../../sdk/go/examples/tasks/main.go),已验证异常场景见 [P1 回归报告](../reports/phase-1.md) 及 [取消回归](../reports/phase-3-cancellation.md)。SDK 忽略未知响应字段;更改已有字段语义需升级契约和回归。
|
||||
|
||||
@@ -35,6 +35,7 @@ ACK 的 body 根据原请求选择:worker.capacity → welcome,worker.resume
|
||||
- hello.concurrency_keys 可选且默认 false,未声明时不派发带资源键任务;task.assign.task.concurrency_key 与非零字符串 concurrency_token 必须同时出现。Schema 检查字段配对,SDK 另核验支持声明和键格式,事务维护许可;见 [资源键契约](keyed-concurrency.md)。
|
||||
- finish.retryable 为可选布尔值,默认 false;true 仅允许 FAILED,Schema 与服务端都校验。派发任务可带 effect_uncertain=true,表示此前授权执行的效果尚未核实。业务重试条件见 [安全重试](retries.md)。
|
||||
- 返回时间使用 UTC RFC 3339,最多微秒精度。验证器应开启 format 断言以校验实际日历日期。
|
||||
- task.assign.task.retry_of为可选原任务ID,表示人工重试的直接来源;SDK校验合法ID及非自身关联。旧SDK忽略未知响应字段,使用旧版严格Schema的客户端需更新Schema;业务幂等身份不因新taskID变化,见[人工恢复](task-recovery.md)。
|
||||
- task.assign.task.priority 为可选 0–9 整数,零值省略;平台在实际到期后结合等待时间排序,详见 [优先级与公平派发](priority-and-fairness.md)。
|
||||
|
||||
P2 收紧了开发期此前允许的省略控制字段、非规范计数字符串和数组内字段别名。当前 SDK 一直发送完整规范字段,不需迁移;其他自研客户端应按本文件更新。SDK 尚未发布首个版本。将来扩展消息类型或改变字段语义必须同时更新 Schema、服务端、SDK 与兼容回归。
|
||||
|
||||
Reference in New Issue
Block a user