JianFeeeee
de6fa59cbb
fix(pi桥): 排队路径补日志 —— 「在排队」与「丢了」此前在日志上同形
## 起因
压测后重建网关,我发信做端到端验证,**pi 一直没回**。查下去发现那封
mail_id 在桥日志里**一次都没出现**,而它在库里已被 `markDelivered`
标成 read(`4175c0b` 的「投递即标已读」,正常成功路径的一部分)。
真正卡住排查的是:**池满时邮件进 `queue`,而排队路径一句日志都没有。**
于是「这封在排队」与「这封丢了」在日志上**完全同形** ——
当时能给出的结论只有「不知道」。
## 改法
入队/出队各一声,且都带可读数:
· 入队:key、第几位、前面还有几封、在跑 `activeCount/maxWorkers`、第几次尝试
· 出队:**等了多久**(秒)、剩几封在排
`attempt>1` 单独标出 —— 那是**重投**(上次没回报 done),与首次排队不是一回事,
混在一起会让人以为是同一种等待。
## ★ 两次错误归因(都记在 DEBTS 里,因为推理方式会复发)
**① 「是 read_inbox 连带标掉了在途邮件」** —— 错。
我看到 `status` 在 11ms 内变 read 就归因到 read_inbox。
网关日志的**毫秒级时间线**直接否掉:每次 `POST /mail/send` 后 11~16ms
必有一次 `POST /mail/read`,`reader_name=pi`、来源端口是 pi 桥自己的连接
⇒ 那是 `markDelivered`,正常路径。
**② 「是 opencode 的桥串用了 pi 的密钥」** —— 错。
我一度以为 `reader_name=pi` 与「连接来自 opencode 进程」矛盾。
实测两个 CONFIG_DIR 不同、各自的 key 在库里分别属于 pi / opencode。**没有串用。**
★ 共同点:**我先有了候选解释,再去找支持它的证据**。
正确顺序是「先取一条能一次说清的独立时间线,再解释」。
## 顺带纠正我自己上轮的一个测量假象
我曾说「实测同一时刻 4 个 worker 在跑,MAX_WORKERS=3 被绕过」——
**错的**。`pgrep -f` **把执行查询的那条命令自己算进去了**(它含同样的字符串)。
用 `ps -eo pid,args | grep -E "node .*/worker\.mjs$" | grep -v grep` 实测是 **3 个**,
与上限一致。探针把自己算进来 —— 与 `baseline-residue` / `python-probe-shadowing` 同族。
## 判据
新增 `test/queue-observability.test.mjs`(4 格,钉**形状**不钉读数 ——
读数要真把池压满才有):
入队/出队各有一声、出队那声必须含等待时长、入队那声必须带占用比、
以及一条自检(删掉入队日志后源码里确实没有它 ⇒ 判据恒绿的话会先红)
变异验证:删掉入队日志 ⇒ **4 格全红**。
全套:pi 530 / opencode 351 / dsh 426,全绿;共用 lib 一致性 ✅。
2026-09-28 10:40:01 +08:00
..
2026-09-11 11:32:47 +08:00
2026-09-28 09:40:15 +08:00
2026-09-28 10:40:01 +08:00
2026-09-28 10:40:01 +08:00
2026-09-14 20:00:16 +08:00