fix: 代码审查后续——改任务不再重新生成、顶替与改排期的原子性、分片上限按最长类型算 - #87
Merged
Merged
Conversation
- 「这次触发的内容有没有落定」不再看 retry_count:改任务会把重试计数清零,于是
用户在重试窗口里随手改一下,重试那一跳就重新调 LLM 生成一整条,旧那批还在
outbox 里等补收,同一时刻冒出两份内容。现在每次投递都去 outbox 认这次触发的
批次,认到只补推送。
- pg / neon 补上 createTaskSuperseding(一条数据修改型 CTE,INSERT 抛错时 DELETE
跟着回滚)。自定义适配器的两步退路改成先建新、后删旧:反过来的话建新失败会把
旧任务白删,客户端还以为它在。
- 三个适配器的 updateTaskByUuid 在改 next_send_at 时加租约门:任务正被投递占着
就不改。PUT /update-message 回 409 TASK_IN_FLIGHT,renewTask 回
{ renewed: false, reason: 'in_flight' },不再假装成功。只改正文不受影响。
- 分片上限校验的探针改用最长的 messageKind(tool_request),之前按 reasoning 量
少算 3 字节,配在上限附近的部署里 tool_request 的分片会被整批拒收。
回归守卫:改任务后仍只补推送、顶替失败时旧任务还在、投递中改排期被挡(适配器 /
handler / renewTask 三处)、放行的最大分片对每种 messageKind 都成立。
Claude-Session: https://claude.ai/code/session_017fqgW4ShQ4yjJJwqAiJrcT
- 探针之前固定用 reasoning,比最长的 tool_request 短 3 字节:把 maxChunkBytes 配 在上限附近(例如照着报错里建议的最大值配)的部署,tool_request 的分片每片都超 出单条 push 的明文上限、被推送服务拒收。现在从 shared 的枚举里现取最长的那个。 - 导出的 validateClientAuth 与 handler 内部的校验此前是两份内容相同的实现,现在 共用同一份 checkClientToken。两个函数的签名和行为不变,handler 仍用启动时编好 的 token 字节。 Claude-Session: https://claude.ai/code/session_017fqgW4ShQ4yjJJwqAiJrcT
四条当场放弃的路径(窗口走完、分片说法冲突、超 maxTotalBytes、拼不回来)此前没接 收尾抛出的错误,墓碑写失败时异常冒到外层兜底,页面收到的原因一律变成 storage-failed,本来那条具体原因丢了。现在收尾失败按住不外抛、只留日志,仍按本来 那条原因广播一次事件——结论此前已经记进内存兜底表,后续分片照样收不进来。 Claude-Session: https://claude.ai/code/session_017fqgW4ShQ4yjJJwqAiJrcT
gc / content-scan / store 此前各写一份 [A-Za-z0-9_] 的正则,注释互相提醒要和 extractRefs 保持一致;GC 能不能安全回收就取决于这几处完全一致。现在字符集只在 token.js 定义一次,四处判定都走它。行为不变,公共 API 没动。 Claude-Session: https://claude.ai/code/session_017fqgW4ShQ4yjJJwqAiJrcT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
对 57c6db5 以来的改动做了一轮代码审查,这个 PR 收掉确认下来值得修的七条,涉及四个包。
改了什么
几处值得单独说的
改任务为什么会让消息发两遍:一次触发的整批内容落进 outbox 之后推送失败、任务进入重试,这期间用户改任务会把重试计数清零(这是它该做的——修好 apiKey 的任务不该背着旧账),而「这次触发有没有落定的内容」恰好就靠这个计数判断。计数一清零,重试那一跳重新调 LLM 生成一整条,旧那批还在 outbox 里等客户端补收。现在每次投递都直接去 outbox 认这次触发的批次,代价是 D1 部署每次定时触发多一次索引查询(pg / neon 没有 outbox,这一步跳过)。
投递中只挡改排期,不挡改正文:排期正是投递收尾要推进的那一列,投递期间写进去必然被盖掉,所以
PUT /update-message带nextSendAt时回 409TASK_IN_FLIGHT,fire hook 的renewTask回{ renewed: false, reason: 'in_flight' }。正文只影响以后的触发,收尾本来就不覆盖它,照旧放行。投递一般几秒到几十秒,worker 中途没了的话租约 90 秒内到期;等重试的那几分钟任务没被占用,照常能改。分片上限差的那 3 字节:信封里原样带着原消息的 messageKind,探针之前固定用
reasoning,比最长的tool_request短 3 字节。默认分片 1800 字节离上限很远不受影响,只有把maxChunkBytes配到上限附近(例如照着校验失败时建议的最大值去配)才会踩到。测试
每条修复都配了回归测试,都实际验证过「旧代码下会挂、改完能过」。六个包的测试全过(server 631、instant 225、sw 102、blob-store 123,另两个包 106 / 123),
npm run build与 ESM 检查通过。pg / neon 的 SQL 只验到「语句长什么样」(本地和 CI 都没有真 Postgres),新加的那条 CTE 语句和租约门在真库上的执行结果没跑过;D1 那条路径是跑真 SQLite 全程验过的。
审查里没处理的
凭据行数上限的并发绕过、pg / neon 逐条写凭据、sw 里两段 TTL 表的重构,这三条影响都很小,暂不处理。
messages: []拿不到默认 temperature 0.8 这条是 57c6db5 之前就存在的,建议另开一个 PR。https://claude.ai/code/session_017fqgW4ShQ4yjJJwqAiJrcT