feat: add precise task business key and creation time queries

This commit is contained in:
2026-09-17 22:19:36 +08:00
parent a50d5faac7
commit 7641423f9d
32 changed files with 1105 additions and 93 deletions

View File

@@ -1,6 +1,6 @@
# Orbit 功能说明:Pulse 与公共能力
> 版本 0.2 · 2026-09-17。Pulse 与 Weave 首版功能范围已确认;标注“建议”的细节待评审。Weave 具体范围另见流程设计。基础、任务执行、调度、资源控制和可靠订阅已实现;批量受理及独立任务核查/人工重试已实现,查询筛选等继续开发,实现状态见持续开发计划。
> 版本 0.2 · 2026-09-17。Pulse 与 Weave 首版功能范围已确认;标注“建议”的细节待评审。Weave 具体范围另见流程设计。基础、任务执行、调度、资源控制和可靠订阅已实现;批量受理、独立任务核查/人工重试及业务键/创建时间查询已实现,事务Outbox接入等继续开发,实现状态见持续开发计划。
## 1. 目标与责任边界

View File

@@ -168,3 +168,9 @@ P2 服务端已新增会话隔离、两步派发、租约、并发许可、结
核查和重试按认证→应用额度→操作幂等→队列→任务/尝试持锁,事务内校验状态、父任务/计划归属和无活动执行。核查的状态/result、额度释放、审计、回执及结果日志一起提交,结果流锁最后取得。人工重试创建新任务与受理事件,审计关联保存在原任务上;旧终态、旧尝试和迟到证据不覆盖。详见[接口契约](api/task-recovery.md)。
真实v7升级回归检查70个外键全部删除、原任务保留、323个未替换索引组件不变,并单独核验新的重试唯一索引覆盖原两列。已有非法重复重试关联或自关联不会被静默清理;迁移失败需核查实际数据。后续仍禁止外键及级联。
## 000016 任务业务键及创建时间查询
BusinessKey沿用既有可空VARCHAR(191),Go/SQL中文注释明确精确匹配、区分大小写和尾部空格;排序规则显式utf8mb4_0900_bin,历史文本原样保留,不增加模型字段。新增(namespace_id,queue_id,business_key,created_at,id)及增加state的组合索引,配合原两种创建时间索引覆盖有无状态/业务键的四种查询。
HTTP/SDK创建时间范围使用包含下界、不包含上界;v2游标以固定长度摘要绑定全部规范化筛选,当前权限逐页校验。单项提交、计划生成和人工重试仅把Go空字符串映射为NULL,不用连接排序规则折叠空格。仍为35个实体、289个中文注释字段,无外键/级联;具体接口与升级边界见[查询手册](api/task-queries.md)。

View File

@@ -27,7 +27,7 @@
| P0 基础与数据模型 | Go workspace、独立 SDK module、公共/Pulse/Weave 模型、MySQL 迁移、配置、健康检查 | 编译/竞态/静态检查;真实 MySQL 建表、隔离、唯一性、预算、不可变版本、迁移失败防护;SDK 健康调用 | 已完成并通过阶段回归(见 P0 报告) |
| P1 任务受理闭环 | 应用凭据与作用域权限、队列、幂等提交、查询、待执行取消、受理事件;SDK 客户端 | API/SDK 创建查询闭环;重复键与内容冲突、响应未确认重报、跨命名空间拒绝、参数边界 | 已完成并通过阶段回归(见 P1 报告;真实断路/提交 ACK 丢失注入留后续故障阶段) |
| P2 Worker 执行闭环 | WSS 接入、能力/容量、领取与开始、租约、续租、结果确认、排空与恢复;Worker SDK | 真 Worker 执行;失联/重连/重复确认/旧尝试拒绝;业务效果未知转核查;节点故障接管 | 已完成并通过阶段回归:服务端、自动 SDK、历史查询、完整 Schema 与真实进程强杀恢复;测试拓扑和剩余生产故障矩阵见 P2 验收报告 |
| P3 Pulse 完整能力 | 安全重试、延时、Cron/固定间隔、漏跑策略、计划版本、运行中取消、并发许可、配额/背压、可靠结果订阅、批量受理、独立任务核查/人工重试、查询筛选与事务Outbox接入 | 多实例领取/触发竞争、重试上限、取消竞争、队列隔离、积压恢复、事件重复交付 | 进行中:安全重试、计划调度、运行中取消、队列控制/限速/积压背压、跨命名空间应用配额、显式资源键许可及 SDK 场景已实现并通过全量回归;优先级及节点公平派发已实现并通过全量回归;可靠订阅核心、HTTP/WSS、管理 SDK 和管理示例已实现并回归;消费 SDK、协议示例及两项节点强杀回归已完成;业务 Inbox 场景、COMMIT响应丢失及消费者进程故障回归已完成;批量受理、SDK、接口与部分补交示例已完成全量回归;独立任务核查/人工重试、审计查询、两次真实HTTP回执丢失及完整示例已通过全量回归;业务键/时间筛选与事务Outbox接入待完成 |
| P3 Pulse 完整能力 | 安全重试、延时、Cron/固定间隔、漏跑策略、计划版本、运行中取消、并发许可、配额/背压、可靠结果订阅、批量受理、独立任务核查/人工重试、查询筛选与事务Outbox接入 | 多实例领取/触发竞争、重试上限、取消竞争、队列隔离、积压恢复、事件重复交付 | 进行中:安全重试、计划调度、运行中取消、队列控制/限速/积压背压、跨命名空间应用配额、显式资源键许可及 SDK 场景已实现并通过全量回归;优先级及节点公平派发已实现并通过全量回归;可靠订阅核心、HTTP/WSS、管理 SDK 和管理示例已实现并回归;消费 SDK、协议示例及两项节点强杀回归已完成;业务 Inbox 场景、COMMIT响应丢失及消费者进程故障回归已完成;批量受理、SDK、接口与部分补交示例已完成全量回归;独立任务核查/人工重试、审计查询、两次真实HTTP回执丢失及完整示例已通过全量回归;业务键/创建时间筛选、SDK与示例已通过全量回归;任务详情来源追踪与事务Outbox接入待完成 |
| P4 Weave 主流程 | SDK 定义构建与发布校验、实例、顺序/分支/结构化并行汇合、信号/定时等待、版本绑定 | 重启接续、早到/重复信号、并行竞争、内部事件重放、发布版本兼容;端到端通用流程 | 待开发 |
| P5 Weave 恢复与查询 | 有界查询、暂停继续、取消、人工核查恢复、控制门控与审计 | 轮次与尝试独立预算;暂停/开始/回执/超时竞争;恢复保留预算;未知结果不盲目重复 | 待开发 |
| P6 生产验证与运维 | 完整监控、凭据轮换、备份恢复、滚动升级、运行手册、可复现负载和故障工具 | 对照生产验收清单执行,报告环境/指标/遗留项;容量、RPO/RTO 按真实拓扑验证 | 待开发 |
@@ -43,7 +43,8 @@ SDK、文档与示例随 P1–P5 同步开发,P7 是全量核对,不是最
| --- | --- |
| 批量任务受理 | 已实现[批量API](api/batch-tasks.md)、独立SDK及[补交示例](examples/batch.md);真实MySQL部分失败与HTTP响应丢失用例已通过,同键并发20轮及全量回归已通过,见[报告](reports/phase-3-batch-tasks.md) |
| 独立任务人工核查与重试 | 已实现[管理API及SDK](api/task-recovery.md)、专门权限、显式安全声明、证据/版本/审计和关联新任务;[完整场景](examples/recovery.md)及[回归报告](reports/phase-3-task-recovery.md)同步交付 |
| 任务查询筛选 | [当前ListTasks](../sdk/go/types.go) 仅队列/状态/分页;需按业务关联键及创建时间范围查询,游标绑定所有筛选,保持授权与有界索引扫描 |
| 任务查询筛选 | 已实现[业务键及创建时间查询](api/task-queries.md),v2游标绑定全部筛选、旧游标受限兼容、四种索引路径与[完整场景](examples/task-query.md);[回归报告](reports/phase-3-task-queries.md)同步记录 |
| 任务详情来源追踪 | 原功能要求能查看关联计划;当前TaskView未返回来源计划/触发记录。需补齐任务到计划及触发版本的查询,验证当前权限、同命名空间归属与来源缺失处理;流程来源随Weave接入 |
| 业务到平台的事务Outbox接入 | [事务Outbox设计](04-reliability-and-data.md#61-业务系统到平台) 尚缺完整接入示例;需业务变更与待发请求同事务、稳定提交身份、响应不明核对和发送恢复,保持核心SDK无ORM/数据库依赖 |
凭据安全重绑、历史清理、全量监控/容量与MySQL故障切换仍按P6执行;Weave的通用执行门控/内部事件接续随P4–P5落实,不将外部结果订阅当作内部流程引擎。
@@ -64,6 +65,7 @@ SDK、文档与示例随 P1–P5 同步开发,P7 是全量核对,不是最
| 优先级与应用隔离 | 近同时到期按优先级 → 旧任务等待补偿 → 应用/队列轮转 | P3,已实现完整示例 |
| 可靠结果订阅 | 冻结结果 → 持久化交付 → Inbox 去重 → 确认/补发 → 耗尽后人工重试 | P3,核心、HTTP/WSS、管理及消费 SDK、独立Inbox示例与真实进程故障回归已完成 |
| 批量文件作业受理 | 逐项身份 → 部分结果 → 同键核对 → 释放额度 → 只补交失败项 | P3,已实现完整示例 |
| 业务操作定位 | 精确业务键 → 创建区间 → 游标分页 → 查询详情 | P3,已实现完整示例 |
| 独立任务人工恢复 | 未知结果 → 证据核查 → 保留原任务 → 关联新任务 → 审计查询 | P3,已实现完整示例 |
| 并行生成结果 | 发布流程 → 并行执行 → 汇合 → 完成 | P4 |
| 审核与外部回执 | 提交流程 → 等待信号 → 授权信号注入 → 继续 | P4 |
@@ -98,6 +100,7 @@ SDK、文档与示例随 P1–P5 同步开发,P7 是全量核对,不是最
- [P3 业务 Inbox 与消费者故障回归](reports/phase-3-result-inbox.md)
- [P3 批量任务受理回归](reports/phase-3-batch-tasks.md)
- [P3 人工核查与重试回归](reports/phase-3-task-recovery.md)
- [P3 业务键与时间查询回归](reports/phase-3-task-queries.md)
- [接口手册](api/README.md)
- [SDK 接入](sdk/README.md)
- [通用场景示例](examples/README.md)

View File

@@ -2,7 +2,7 @@
- 文档版本:0.2
- 整理日期:2026-09-17
- 阶段:P0–P2 已通过阶段验收;P3 安全重试、计划调度、运行中取消、队列资源控制和应用共享配额已通过回归,资源键许可及真实进程恢复已通过全量回归,优先级/节点公平派发及真实隔离场景已通过全量回归,批量任务受理和独立任务人工核查/重试已实现,数据库已改为无外键,P3–P7 继续推进,尚未完成全平台生产验收
- 阶段:P0–P2 已通过阶段验收;P3 安全重试、计划调度、运行中取消、队列资源控制和应用共享配额已通过回归,资源键许可及真实进程恢复已通过全量回归,优先级/节点公平派发及真实隔离场景已通过全量回归,批量任务受理、独立任务人工核查/重试及业务键/时间查询已实现,数据库已改为无外键,P3–P7 继续推进,尚未完成全平台生产验收
- 适用范围:Orbit 统一平台,包含 Pulse 任务调度模块、Weave 流程编排模块与公共能力。平台面向多个业务系统复用。
## 阅读顺序

View File

@@ -8,7 +8,7 @@
| --- | --- | --- |
| `GET /health/live` | 已实现 | [健康检查](health.md) |
| `GET /health/ready` | 已实现,验证数据库、迁移记录及零外键要求 | [健康检查](health.md) |
| `/v1/tasks` 提交、查询、分页与待执行取消 | P1 已实现 | [任务接口](tasks.md) |
| `/v1/tasks` 提交、查询、分页与待执行取消 | 已实现,P3扩展业务键与创建时间筛选 | [任务接口](tasks.md) / [查询契约](task-queries.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) |

117
docs/api/task-queries.md Normal file
View File

@@ -0,0 +1,117 @@
# 按业务键与创建时间查询任务
状态:P3 已实现HTTP、Go SDK及[运行示例](../examples/task-query.md)。这是 `GET /v1/tasks` 的扩展,返回任务摘要,查询不执行或重试任务。验证记录见[本阶段报告](../reports/phase-3-task-queries.md)。
## 1. 权限与字段
请求使用 `Authorization: Bearer <token>`,需要当前命名空间的 `tasks:read` 及指定队列范围,不携带幂等键。命名空间由凭据确定,不接受调用方指定。队列不在权限范围返回403;有权限但不存在该队列/无匹配任务时返回空列表,不披露其他命名空间资源。
| 参数 | 类型与默认 | 要求 |
| --- | --- | --- |
| queue_id | string,必填 | 32位小写十六进制队列标识 |
| state | string,可选 | WAITING、LEASED、RUNNING、NEEDS_REVIEW、SUCCEEDED、FAILED、CANCELLED之一;省略表示所有状态 |
| business_key | string,可选 | 1–191个Unicode字符,无NUL/回车/换行;精确关联匹配,显式空值拒绝 |
| created_from | RFC3339时间,可选 | 创建时间下界,包含该时刻 |
| created_before | RFC3339时间,可选 | 创建时间上界,不包含该时刻;与下界同时给出时必须更晚 |
| limit | integer,默认20 | 1–100;可以在翻页时更改 |
| cursor | string,可选 | 上页next_cursor,最长1024字符,必须保持其他筛选不变 |
参数只能出现一次,未知名称、非法百分号编码、空时间、日期字符串、非规范状态或非法范围返回400。时间允许RFC3339时区偏移并规范化UTC;精度最多到微秒,UTC年份2000–9998。上下界可以仅给一个,不设置默认时间窗口。JSON的null不是URL查询值,省略参数才表示不设该条件。
business_key区分大小写、重音字符、Unicode编码形式以及尾部空格。例如 `object:1`、`object:1 `、`Object:1` 是不同键;`é` 与 `e` 加组合重音也不同。不修剪/规范化输入,不使用LIKE,`%` 和 `_` 是普通字符;关联键不承担业务幂等。纯空格键若已提交也按原值匹配,空字符串提交仍表示没有关联键;本接口不提供“只查无关联键”筛选。
## 2. 完整请求和响应
使用URL编码,尤其是键中的 `+`、`%`、空格和时间中的时区加号:
```sh
curl --get "$ORBIT_URL/v1/tasks" \
-H "Authorization: Bearer $ORBIT_TOKEN" \
--data-urlencode "queue_id=$ORBIT_QUEUE_ID" \
--data-urlencode 'business_key=object:operation-001' \
--data-urlencode 'state=FAILED' \
--data-urlencode 'created_from=2026-09-17T00:00:00Z' \
--data-urlencode 'created_before=2026-09-18T00:00:00Z' \
--data-urlencode 'limit=20'
```
HTTP200完整示意响应:
```json
{
"request_id":"44444444444444444444444444444444",
"data":{
"items":[{
"id":"22222222222222222222222222222222",
"queue_id":"11111111111111111111111111111111",
"state":"FAILED",
"revision":"4",
"handler":"object.prepare",
"handler_version":"v1",
"business_key":"object:operation-001",
"available_at":"2026-09-17T00:00:00Z",
"deadline_at":"2026-09-17T00:01:00Z",
"attempt_count":1,
"created_at":"2026-09-17T00:00:00Z",
"updated_at":"2026-09-17T00:00:01Z"
}]
}
}
```
有下一页时data还包含next_cursor字符串;没有匹配时items为 `[]`。摘要不携带payload/result/冻结策略/retry_of,按需调用 `GetTask` 获取详情。字段完整说明见[任务接口](tasks.md)。不返回全量总数或大offset接口。
## 3. 分页与并发语义
固定按 `(created_at DESC,id DESC)` 排序。相同创建时间以任务ID打破平局;取消、执行和核查改变状态/updated_at,不改变创建排序键。每页取至多limit+1行以判断下一页。
v2游标同时绑定命名空间、队列、状态、精确业务键和规范化UTC时间界限;长业务键通过固定长度摘要绑定,191字符的合法键不会撑破游标上限。修改/删除任何筛选、混用其他命名空间或传入非法游标返回400,不能通过更换参数扩大原页查询。游标是排序位置,不是授权证明,每页都重新校验当前凭据和队列范围。
跨页不是数据库快照:遍历期间新增任务、任务状态变化可能影响后续页面,不能将动态状态查询当作完整审计导出。新任务排在已读位置之前时,从首页刷新才会看到;状态筛选的任务离开该状态时可能从后续页面消失。需要可靠处理结果使用[结果订阅](subscriptions.md),核对历史使用[执行历史](execution-history.md)与[操作审计](task-recovery.md)。
旧版未带版本的游标仅兼容原队列/状态查询,不能附加业务键或时间界限。SDK把游标当不透明字符串,不应解析、改写或自行拼接。
## 4. SDK调用
`Client.ListTasks(ctx, orbit.ListTasksRequest)` 返回 `TaskPage`。新增字段BusinessKey、CreatedFrom、CreatedBefore,其余字段保持不变。BusinessKey空字符串在SDK中表示省略,时间指针nil表示无该界限。
```go
query := orbit.ListTasksRequest{
QueueID: queueID,
State: orbit.TaskFailed,
BusinessKey: "object:operation-001",
CreatedFrom: &from,
CreatedBefore: &before,
Limit: 20,
}
for {
page, err := client.ListTasks(ctx, query)
if err != nil { return err }
for _, task := range page.Items {
fmt.Println(task.ID, task.State, task.CreatedAt)
}
if page.NextCursor == "" { break }
query.Cursor = page.NextCursor
}
```
片段假设已有客户端及time.Time类型from/before;完整可运行源码见[示例](../../sdk/go/examples/task-query/main.go)。SDK校验ID、范围、状态、键长度/UTF-8及时间精度,并用url.Values编码,时间转UTC,不修改调用方时间对象。超时只影响读取,可保持条件重新请求;没有自动重试或自动翻页。
## 5. 存储、升级与边界
迁移000016明确business_key使用 `utf8mb4_0900_bin`,保证尾部空格有意义;现有文本不重写、不修剪,不增加模型字段或数据库外键。单项受理、计划触发和人工重试按Go字符串是否为空决定NULL,不依赖连接排序规则的NULLIF比较。
查询使用四个固定索引之一,全部将等值过滤放在创建时间及ID之前:
| 筛选组合(均含命名空间与队列) | 索引 |
| --- | --- |
| 无状态/业务键 | ix_task_created |
| 状态 | ix_task_state_created |
| 业务键 | ix_task_queue_business_created,新增 |
| 业务键与状态 | ix_task_queue_business_state_created,新增 |
上下界与游标在索引时间范围内继续扫描,不按全部任务取回后内存过滤。SQL索引名来自固定服务端分支,查询值全部参数化。实际MySQL执行计划验证四组走对应range/ref索引且无filesort;这是查询路径验证,不是生产吞吐或百万租户容量证明。
升级需先停止旧写入节点、应用迁移,再统一启用新版节点;列排序规则和索引调整会有DDL成本,应演练目标规模维护窗口。新SDK查询旧节点时,新参数会被拒绝,不能删除筛选后自动降级。新旧节点混合分页与生产滚动升级尚未验收。
通用400/401/403/503错误见[任务手册](tasks.md)。业务键与时间查询不新增权限,不授予执行、取消或人工核查权限。

View File

@@ -124,8 +124,12 @@ SDK:`Client.GetTask(ctx, taskID)`。
| --- | --- |
| queue_id | 必填,有权限的队列 ID |
| state | 可选,取上述状态之一 |
| business_key | 可选,精确匹配1–191个Unicode字符,区分尾部空格;显式空值拒绝 |
| created_from / created_before | 可选,RFC3339微秒时间;创建时间包含起点、不包含终点,两者同时设置时起点必须更早 |
| limit | 可选,默认 20;1–100 |
| cursor | 可选,上一页返回值;必须保持 queue_id/state 不变,最长 1024 字符 |
| cursor | 可选,上一页返回值;必须保持队列、状态、业务键和时间范围不变,最长1024字符 |
完整筛选、时间边界、索引与兼容说明见[业务键与时间查询](task-queries.md),并提供[完整运行示例](../examples/task-query.md)。
按 (created_at DESC, id DESC) 游标分页,不使用大 offset。不承诺跨页快照:读取过程中状态可能变化。列表省略 payload/result/retry 等大字段,返回摘要。

View File

@@ -146,3 +146,10 @@
- 预期:原任务FAILED、新任务SUCCEEDED,原尝试和审计保留;管理凭据显式--recovery-access。
- 异常:真实HTTP在核查/重试提交后丢响应,原身份恢复同一审计和新任务;迟到成功只进入证据。
- 范围:本例不操作外部系统,不能替代真实证据核查、业务幂等或持久化管理操作Outbox。
## 已可运行:业务键和创建时间查询
- 源码:[task-query](../../sdk/go/examples/task-query/main.go),[完整启动与异常说明](task-query.md)。
- 步骤:提交三个模拟任务 → 精确业务键及时间范围过滤 → 每页一条遍历 → 验证上界排除 → 取消收尾。
- 预期:matched=2、pages=2、before_excluded=true、cancelled=3。
- 范围:普通提交/读取/取消权限;不调用外部系统、不启动Worker,所有历史保留,状态分页不是数据库快照。

View File

@@ -0,0 +1,36 @@
# 业务键与时间范围查询示例
源码:[task-query/main.go](../../sdk/go/examples/task-query/main.go)。本例提交三个模拟对象任务,不启动Worker,演示精确业务键、创建时间区间和任务摘要分页。
## 准备与运行
按[SDK初始化步骤](../sdk/README.md)迁移数据库、初始化专用开发队列及普通提交/读取/取消凭据,启动当前Orbit服务。从仓库根目录执行:
```sh
cd sdk/go
ORBIT_URL=http://127.0.0.1:8080 \
ORBIT_CREDENTIALS_FILE=../../.local/development.credentials.json \
go run ./examples/task-query
```
也可使用ORBIT_TOKEN与ORBIT_QUEUE_ID,环境值优先。无需额外管理权限,凭据秘密不输出。队列应有至少三个未终结任务空位;每次运行的处理器与业务键带独立标识,避免已有任务干扰。
## 实际调用与结果
1. 提交两个完全相同业务键的任务,以及一个只相差尾部空格的任务。业务键含中文、加号、百分号及重音字符。
2. 用服务端回执中的CreatedAt设置包含起点、不包含终点的时间范围,避免依赖客户端时钟同步。
3. ListTasks按原键、WAITING状态和创建区间查询,每页1条,沿NextCursor遍历;仅匹配前两个任务。
4. 将created_before设为第二个任务的精确创建时间,确认它被排除,只剩第一个任务。
5. 分别取消本例三个任务,保留任务、受理与取消审计。
预期输出:
```text
matched=2 pages=2 before_excluded=true cancelled=3
```
重复运行创建新的独立样本。代码没有外部业务副作用,也不删除数据库历史。失败非零退出,可能留下已受理任务;用回执、业务键和时间范围查询后核对,各任务总时限60秒,当前示例没有Worker会进入未开始超时处理。
完整参数、游标兼容和异常说明见[查询契约](../api/task-queries.md)。翻页时保持所有筛选,发生INVALID_ARGUMENT不要丢弃过滤条件“兜底查全部”。状态变化的跨页结果不是快照,不能当作完整审计导出。
`make integration` 会在一次性MySQL中运行此示例及实际HTTP SDK回归,验证原键/尾部空格、时间边界、分页、变更条件拒绝,以及取消后创建时间不改变。

View File

@@ -0,0 +1,75 @@
# P3 业务键与创建时间查询回归
验证日期:2026-09-17。当前已实现服务端、SDK、迁移、接口及可运行场景;全量回归已正常退出,状态码0。P3的任务详情来源追踪和业务事务Outbox接入仍待交付,不能据此宣布Pulse或全平台完成。
## 1. 实现证据
- [服务输入](../../pulse/service/service.go):精确业务键、UTC创建时间下界/上界、有限页大小,非法值不进入存储。
- [查询存储](../../internal/storage/mysql/task_query.go):固定四种索引分支、参数化SQL、创建时间/ID游标分页,v2摘要绑定全部筛选,旧游标只兼容原队列/状态查询。
- [HTTP入口](../../internal/transport/httpserver/tasks.go)与[独立SDK](../../sdk/go/task_query.go):URL编码、UTC规范化、显式空参数与未知参数拒绝,SDK无数据库依赖。
- [迁移000016](../../internal/storage/mysql/migrations/000016_task_query_filters.up.sql):business_key使用精确NO PAD二进制排序,增加两种队列业务键索引,中文字段含义同步。无新增模型字段、无外键/级联,仍为35个模型、289个持久化字段。
- [接口手册](../api/task-queries.md)、[完整示例说明](../examples/task-query.md)及[源码](../../sdk/go/examples/task-query/main.go)。
## 2. 真实数据库验证
[TaskQuery集成](../../internal/storage/mysql/task_query_integration_test.go)使用真实受理任务,仅将测试创建时间调为精确边界来建立确定性数据:
1. 相同业务键不同任务、相同创建时间不同ID,按时间/ID倒序逐页遍历,无重复或遗漏。
2. 精确区分尾部空格、大小写、预组合/组合Unicode及无关联键,创建下界包含、上界排除。
3. 同命名空间其他队列、其他命名空间同键任务不进入本查询;191字符键仍生成有界游标并能完整翻页,纯空格键可原样受理与检索。
4. 更改/删除业务键、更改状态/时间/队列/命名空间时,旧游标拒绝;等价UTC时刻及修改页大小仍可继续。
5. 已取得游标后撤销队列范围,继续查询仍被当前权限拒绝。
6. 原版无版本游标仅用于旧查询;重复字段、null、大小写别名、未知字段、未知版本和纳秒时间游标拒绝。
7. 实际HTTP验证Unicode/保留字符编码、显式空键、重复参数、错误日期、非法UTF-8/编码、非法时间范围和未知名称。
8. EXPLAIN FORMAT=JSON对四种筛选验证对应索引、range/ref访问、无filesort。验证的是查询计划,不是生产吞吐或容量。
旧v7升级测试同时保存包含重音字符和尾部空格的已有业务键,升级后原任务快照不变,原323个未替换索引组件保留,列排序规则正确,外键70→0。应用额度v9升级夹具同步还原新增索引与排序规则再实际重放迁移。
单项受理、计划生成、人工重试只在Go字符串为空时写NULL,避免不同连接排序规则下NULLIF比较把纯空格折叠为空。旧数据不推测补回丢失的值。
## 3. SDK与示例证据
[SDK单元测试](../../sdk/go/task_query_test.go)验证URL编码、时间规范化、精确revision、非法参数本地拒绝;[服务测试](../../pulse/service/task_query_test.go)验证时间/业务键边界与存储隔离。
[真实HTTP SDK集成](../../sdk/go/task_query_integration_test.go)提交同键/尾部空格不同键任务,分页查询、变更条件拒绝、精确时间边界和取消后原创建时间排序均通过。完整示例输出:
```text
matched=2 pages=2 before_excluded=true cancelled=3
```
示例使用普通提交/读取/取消凭据,不增加管理权限,不启动Worker,不调用外部业务系统,保留任务及审计。
## 4. 环境与复现
macOS、Go1.27.1、Docker单实例MySQL8.4.10,隔离数据库、随机测试凭据与回环端口,结束自动清理。
```sh
make fmt test vet build
make integration
```
定向数据库回归已通过(16.148秒,含升级与包开销);新增的真实受理和最长业务键场景随后进入全量回归。普通未配置数据库的go test跳过Integration,不能替代真实数据库验证。
| 验证组 | 本轮实际结果 |
| --- | --- |
| fmt / race / vet / build | PASS |
| 全量MySQL集成 / 任务查询用例 | PASS,101.225 / 0.38秒 |
| SDK Worker完整组 | PASS,90.485秒 |
| SDK计划 / 队列 / 批量 | PASS,5.704 / 4.461 / 1.368秒 |
| 新查询SDK真实HTTP | PASS,1.324秒 |
| SDK订阅管理 / 事件消费 | PASS,33.394 / 51.884秒 |
| SDK人工核查与重试 | PASS,3.405秒 |
| Inbox真实数据库与消费者故障 | PASS,34.643秒 |
| SDK应用配额 | PASS,1.369秒 |
| 九项节点/Worker进程故障 | PASS,60.625秒;连同Inbox消费者共十项进程故障 |
| 全部运行示例 | 17个核心SDK示例 + 1个独立Inbox示例通过 |
完整脚本的终态退出码为0,未以中途日志推断完成。以上耗时是本次正确性回归记录,不是吞吐或容量指标。文档链接、JSON代码块及核心SDK无数据库/服务端依赖检查均通过。
## 5. 已知边界与后续
- 查询需要队列,时间界限可选。结果不含总数、大载荷或跨页快照,不提供前缀/模糊搜索、未设置业务键专用筛选或跨队列聚合。
- 时间相同依赖ID稳定排序,状态可能跨页变化;可靠结果消费使用订阅,历史审计使用已有历史接口。
- v2游标绑定筛选但不是权限证明;旧节点拒绝新参数,不允许删条件降级。新旧二进制混合查询和生产滚动升级尚未验收。
- 新索引增加写入和存储成本;迁移需DDL维护窗口演练,生产规模容量、数据库切换及RPO/RTO仍在P6验证。
- 任务详情尚未返回来源计划/触发记录,已对照原功能清单纳入P3补齐;业务事务Outbox也是剩余接入项;Weave执行与恢复仍按P4–P5推进,持续目标保持原范围。

View File

@@ -119,7 +119,7 @@ fmt.Println(cancelled.Task.State)
| Liveness / Readiness | Health | [健康](../api/health.md) |
| SubmitTask | SubmitTaskRequest / SubmitTaskResult | [任务](../api/tasks.md) |
| GetTask | taskID / Task | [任务](../api/tasks.md) |
| ListTasks | ListTasksRequest / TaskPage | [任务](../api/tasks.md) |
| ListTasks | ListTasksRequest / TaskPage,业务键及创建时间范围 | [查询](../api/task-queries.md) |
| CancelTask | taskID、key、CancelTaskRequest / CancelTaskResult | [任务](../api/tasks.md) |
| CreateQueue | key、CreateQueueRequest / CreateQueueResult | [队列](../api/queues.md) |
| GetQueue | queueID / Queue | [队列](../api/queues.md) |
@@ -128,7 +128,7 @@ fmt.Println(cancelled.Task.State)
| ListAttemptEvidence | taskID、attemptID、HistoryPageRequest / AttemptEvidencePage | [执行历史](../api/execution-history.md) |
| GetAttemptEvidence | taskID、attemptID、evidenceID / AttemptEvidence | [执行历史](../api/execution-history.md) |
所有方法第一个参数为 context.Context,返回值之外都返回 error。计划方法的具体参数见对应手册。命令方法要求调用方提供稳定 key,不自动生成或重试。ListTasksRequest 接受 QueueID、State、Limit、Cursor。
所有方法第一个参数为context.Context,返回值之外都返回error。计划方法的具体参数见对应手册。命令方法要求调用方提供稳定key,不自动生成或重试。ListTasksRequest接受QueueID、State、BusinessKey、CreatedFrom、CreatedBefore、Limit、Cursor;[筛选与游标语义](../api/task-queries.md)和[运行示例](../examples/task-query.md)已提供。
Options.HTTPClient 可注入专用 HTTP 客户端。SDK 复制配置,不修改调用方实例;默认超时 10 秒,可用 context 缩短。禁止自动跟随重定向,避免凭据被转交其他地址。生产配置 HTTPS;SDK 不承担部署 TLS 终止。