fix(usage): preserve full bodies before queue truncation

This commit is contained in:
ZheFox
2026-09-16 13:10:40 +08:00
parent 72a4bf3408
commit 5842c7232e
6 changed files with 216 additions and 4 deletions
@@ -184,6 +184,7 @@
## 第九轮修复状态
- **新增队列消息的完整字节上限:** `AETHER_GATEWAY_USAGE_QUEUE_PAYLOAD_MAX_BYTES` 默认 1 MiB,启用 usage runtime 时显式 `0` 非法。`UsageQueue::enqueue` 在发送 Redis 命令前,以有界 writer 编码完整 v1 JSON envelope,包含 UTF-8、转义、metadata、正文、headers 及其他字段;不会先生成无限制的完整 JSON 字符串再检查长度。普通消息保持原格式,原公开编码接口及历史消息解码继续兼容。
- **FULL 终态正文保留补充:** 正常终态入队发现需要剥离诊断正文时,先用原事件尝试已有的受限数据库直写,成功后不再入队降级副本。该路径仍遵守数据库压力检查、共享写入并发门限和直写门限,不提高队列字节上限;仅队列节点、写入失败或门限饱和时仍允许有界降级,保留计费事实及 `Truncated` 状态。按使用记录 ID 读取详情同时返回四类正文的采集状态,避免将已知截断误报为 `legacy_unknown`。已经丢弃的历史正文无法由此恢复。
- **诊断降级保留计费语义:** 完整消息超限后,先借用检查去掉四份正文和四份 headers 的核心字段大小,核心可容纳才克隆 metadata 并生成诊断投影;复用同一字节缓冲。保留 token、费用、显式零、错误存在性、身份、时间、终态、正文引用、预留 token 和计费维度。按完整 v1 消费者规则保留请求档位、推理参数、响应实际档位及缓存 TTL,并标记被移除的正文为 `Truncated`。显式 `None`、`Disabled`、`Unavailable` 不改为可回退的状态;JSON null 与非对象正文分别按旧解码和权威规则处理。
- **无法安全编码时的失败路径:** 核心仍超限,或去掉正文无法保留原缓存 TTL 计费语义时,返回 `InvalidInput`。终态沿现有有并发限制的数据库路径使用原事件回退;数据库不可用、受压或写入失败时明确返回 `Failed`,保留 first-byte 状态,不误报已入队或已缓冲。这类输入错误不打开 Redis 熔断,也不会无限重试。重试接收前再次校验,覆盖主路径已熔断或入队槽耗尽的旁路;重试 worker 也会终止单条永久失败并继续处理后续条目。
- **指标与临时分配:** 导出队列 payload 上限、诊断降级、编码拒绝及永久重试失败计数。payload 计数是进程级编码尝试,包含入队与重试预校验,不是唯一事件数。超长 tier/reasoning 字符串先检查已有的 64 字节限制,再执行大小写规范化,避免明知非法仍复制整个字符串。