session-mechanism:修目标检查线静默死(P0-97)
病根:闸③ 的静默基准只按 cwds 的两种斜杠形态做 like,而会话自建的排期落库是 转义形态(["E://ProgramData//…"])⇒ 匹配恒假 ⇒ _last_progress_ts() 回 0 ⇒ `if not lp: return None` 静默返回 ⇒ 本区目标检查线 21 小时零日志零告警 (03:00–22:59 每小时 359/360 行日志是"读任务图失败",闸门日志 0 行)。 修: - 新增 _cwds_hit():JSON 解码 + 路径归一的唯一判定(闸④ 与闸③ 共用) - _last_progress_ts() 两路取最大:排期表 + 会话侧痕迹文件;两路全空留限流日志 - 闸③ 静默 return 前补留痕;闸④ 逐条 log 改限流汇总(一夜 2.7 万行刷屏) - 派活单 cwds 改正斜杠形态(⛔ 不再制造转义行) - 检查棒尾节:收口动作必须自己落笔,⛔ 不许派给执行棒(且不越权写「已完成」) - pitfalls 新增 P0-97;selftest 闸④ 判据随变量名放宽(⛔ 不绑死写法) 验证:自检 PASS 110 / FAIL 0;变异对照三档(打死→None+留痕 / 还原→建排期 / 两路全空→三行留痕)
This commit is contained in:
1 parent
20eacef289
commit
510ba9192c
3 files changed
+194
-59
No files matched your search
@@ -3761,3 +3761,36 @@ var r = el.getBoundingClientRect();
|
||||
- **留痕口径**:本次**只加拒收闸**,既有坏行**不动**(用户选 B 案=台账留痕优先)。
|
||||
- 🔴 **写工具的红线**:**凡是"看着成功、其实写坏了"的通道,优先加"当场拒收"** ——
|
||||
报错比静默污染便宜得多;静默污染要等到有人去读那条记录才发现,而那时原因已经不在现场了。
|
||||
|
||||
---
|
||||
|
||||
## P0-97 🔴🔴 **一条 `like` 匹配不上 ⇒ 目标检查线静默死了 21 小时(零日志、零告警、外表全绿)**(★ 2026-10-12 本区实测)
|
||||
|
||||
- **它长什么样**:闸③ 的静默基准 `_last_progress_ts()` 只做一件事 ——
|
||||
取「本工作区排期的 `updated_at` 最大值」,判据是
|
||||
`cwds like '%E:\ProgramData\…%'`(外加正斜杠形态)。
|
||||
- **那一行为什么撞不上**:`automations.cwds` 是 **JSON 数组文本**,现网**两种写法并存**:
|
||||
· 机制自建(`create_check_schedule()`,明确归一过):`["E:/ProgramData/…"]`
|
||||
· **会话自建**(`automation_update`,派活单把 `WS` 的**反斜杠原文**发给会话):`["E:\\ProgramData\\…"]`
|
||||
⇒ 单反斜杠/正斜杠两种 `like` **都撞不上转义出来的双反斜杠** ⇒ `max(updated_at)` 为 `None`。
|
||||
- **后果链(这才是要命的地方)**:`_last_progress_ts()` 回 `0` ⇒ 闸③ 那句
|
||||
`if not lp: return None` **静默**返回 ⇒ 每 20 秒一次、**一行日志都不写**
|
||||
⇒ 「读不到判据」与「静默还不够久」在日志里**长得一模一样** ⇒
|
||||
**目标检查线 21 小时一条棒都没建,没有任何告警**。
|
||||
实测读数:`03:00–22:59` 每小时 360 行日志里 **359 行是「读任务图失败」**,闸门日志 **0 行**。
|
||||
- **触发它的小动作**:02:24 把本区旧排期整批标删 ⇒ 表里只剩**一条**本区排期,
|
||||
而它恰好是会话用反斜杠建的 ⇒ 判据从"能读"变成"恒读不到",**没有任何提示**。
|
||||
- **✅ 已修(三处,缺一不可)**:
|
||||
① 新增 `_cwds_hit()` —— **JSON 解码 + 路径归一后比**,成为唯一判定,
|
||||
`_last_progress_ts()`/`ws_pending_schedules()` 共用(⛔ 不许在调用方再拼一组 `like`);
|
||||
② `_last_progress_ts()` **两路取最大**:排期表 + **会话侧痕迹文件**(`goal.json`/`tasks.json`/目标执行状态文档)
|
||||
⇒ 排期表为空也能开闸;两路全空 ⇒ **留一行限流日志**(⛔ 不再静默);
|
||||
③ 闸③ 那句 `return None` 前面补 `log_throttled`,**把"为什么不开闸"写进日志**。
|
||||
另:派活单里的 `cwds` 改成正斜杠形态(与会话用同一形态,⛔ 不再制造转义行)。
|
||||
- **变异对照(做过的,不是推理)**:把 `_last_progress_ts()` 打死成 `0.0` ⇒ 闸③ 返 `None` +
|
||||
打出留痕行;还原 ⇒ **当场建排期**;再把"排期表 + 痕迹文件"两路一起弄瞎 ⇒ 返 `None` + 打三行留痕
|
||||
(库读失败/两路全空/闸③ 不建)。⇒ 判据既不是恒绿,也不是恒红。
|
||||
- 🔴 **通则**:**凡是 fail-safe 的"静默 return",都必须留一行限流日志** ——
|
||||
静默的 fail-safe 与"正常的等待"在日志里不可区分,等于把排查线索整条抹掉(同族:P0-52)。
|
||||
另一条:**判据的取值形态不要靠"我想到的几种写法拉倒"** —— 形态是别人写进来的,
|
||||
能想到三种就会漏第四种,而漏掉的那种是**静默**的。要么归一(解码+规范),要么别用字符串匹配。
|
||||
Reference in new issue
Block a user