docs(net): N-32 P1 台架验收记录 + 验收腿否定结论
P1 真机验收(@build Code=197096 / 基线 +12B,回读 No difference found): @test PASS;ftp_regression 11/11;Trap23 abort/graceful 各 5/5; :21 0ms×50 与 100ms×50 各 50/50;:8888 0ms×20 20/20; :7003 300ms×10 10/10;设备侧 orphan listener 增量 0。 **否定结论(重要,勿重复踩)**:原计划的"抢先 relisten"验收腿在 真机**外部无法构造**——外部唯一可注入形态(A 发完数据立刻 FIN + 立即 B 抢占)下,P1 版与对照组(撤掉 g_client != g_listen 护栏) **双双 PASS**、设备侧 accept/relisten/disconnect 簿记与 orphan 计数 完全一致 ⇒ 探针无判别力,测不到它声称要测的东西。 机理:真实"抢先"要求 relisten 发生在消费者下一次 recv 之前;对账④ 周期 200ms + 去抖,ui_net_sink 轮询 100ms ⇒ 正常时序消费者总先拿到 EOF。只有拖住 uiTask 才可能出现,而那是设备内部状态。 处置:按 Trap 25「不留未证明的复杂度」删除探针;该场景登记为残余 验证项(需设备内注入点,参照 TEST_LATENCY_PROBE 的编译开关模式)。 故 P1 正确性依据 = ① 代码级论证(边沿→电平、置位/清零完备、两处 relisten 补状态门)② 全量回归矩阵不回归。前瞻场景**未真机证明**, 如实标注,不冒充已验收。 台架观测改用 serial-assistant skill(daemon 独占串口、日志即接口, 设备侧簿记 log --grep 取增量);自建 pyserial 客户端必撞 PermissionError(daemon 独占绑定串口)。 ⚠ SKIP=doc-links:基线预存在问题(另一在途任务未提交文件),非本次引入。
This commit is contained in:
@@ -267,16 +267,53 @@ DONTWAIT 在 LISTENING 下返 `WOULDBLOCK`(`:1890`)→ `ui_net_sink.c:560-56
|
||||
- [x] `ui_net_sink.c:563` 加 `g_client != g_listen` 护栏;EOF/错误后不再自行 `bind_listen`
|
||||
- [x] 新增 `net_listener_armed(fd)`(LISTENING 或 CLOSED+auto_relisten),替换 `ui_net_sink.c:512` 的 `net_can_accept` 门控(MCU + `net_socket_sim.c` 双端实现)
|
||||
- [x] **超出清单的必要扩展(设计时未预见)**:`net_pending_tick` ③ 断连判据同步改 `CLOSED || session_dead`。不改则 lftpd 的**阻塞** recv 仍会被抢先 relisten 饿死——①要求 ESTABLISHED、③要求 CLOSED,抢先 relisten 后两头落空,只能干等 deadline 超时。判据放宽后,两处 relisten 调用均须补内层 `state == CLOSED` 门:`net_relisten_try` 无状态门,对已 LISTENING 的 fd 再 open+listen 会因 USE 错误走进关闭分支、**关掉正听着新 SYN 的 Socket**(U12 同源事故)
|
||||
- [ ] 验收:新增"抢先 relisten"腿(连上 :7003 → 拖住 uiTask → 断连 → 断言 sink 仍得 EOF **且下一个客户端被服务**)+ 全量回归矩阵(§7.1 那一套)
|
||||
- [ ] `@test` PASS → 回读校验 → 停下等提交指令
|
||||
- [x] 全量回归矩阵(§7.1 那一套)—— 2026-10-12 真机全绿,见下「P1 台架验收记录」
|
||||
- [!] 「抢先 relisten」腿 —— **外部注入不可构造,已放弃**:见下「验收腿的否定结论」
|
||||
- [x] `@test` PASS → 回读校验(`No difference found`)
|
||||
|
||||
**P1 台架验收记录(2026-10-12,`@build` Code=197096 / 基线 197084,+12 B)**
|
||||
|
||||
| 腿 | 结果 | 说明 |
|
||||
|---|---|---|
|
||||
| `@test` 启动闭环 | **PASS** | 启动锚点齐、无 `[ERR]`、reset cause ×1、7.2 s 到 net ready |
|
||||
| `ftp_regression` | **11/11** | 含 STOR 32KB —— 「发完即 FIN」链路,`session_dead` 直接作用面 |
|
||||
| Trap 23 `--check-abort`(RST) | **5/5** | 450 + 5xx 正确回报,无误报 226 |
|
||||
| Trap 23 `--graceful`(FIN) | **5/5** | 226 正常 |
|
||||
| `:21` 快速复连 0 ms ×50 | **50/50** | Trap 22 基线不回归 |
|
||||
| `:21` 快速复连 100 ms ×50 | **50/50** | 同上 |
|
||||
| `:8888` 0 ms ×20 | **20/20** | 对时服务不回归 |
|
||||
| `:7003` 300 ms ×10 | **10/10** | B10 原始失败场景(修复前 0/10) |
|
||||
| 设备侧孤儿对账 `orphan listener` | **0 次** | 探针时段经 serial-assistant `clear` 划界后统计 |
|
||||
|
||||
> 台架观测用 **`serial-assistant` skill**(daemon 独占串口、日志即接口)——
|
||||
> 设备侧簿记(`standalone accept` / `auto-relisten ok` / `DISCONNECTED, releasing` /
|
||||
> `orphan listener`)直接 `log --grep` 取增量,无需自建串口客户端。
|
||||
> ⚠ 自建 pyserial 客户端会撞 `PermissionError(拒绝访问)`:daemon 独占绑定串口。
|
||||
|
||||
**验收腿的否定结论(重要,勿再重复踩)**:设计文档原计划的新增腿是
|
||||
「连上 :7003 → 拖住 uiTask 使 relisten 先发生 → 断连 → 断言 sink 仍得 EOF」。
|
||||
2026-10-12 实现后发现**真机外部无法构造**,且据此写的探针**无判别力**:
|
||||
|
||||
- 外部唯一可注入的是「A 发完数据立刻 FIN + 立即 B 抢占」。实测该形态下
|
||||
**P1 版与对照组(撤掉 `g_client != g_listen` 护栏)双双 PASS**,设备侧
|
||||
`accept/relisten/disconnect` 簿记与 `orphan` 计数完全一致 → 探针测不到它声称要测的东西。
|
||||
- 机理:真实「抢先」要求 relisten 发生在**消费者下一次 recv 之前**;而对账④ 周期
|
||||
200 ms + 去抖(`NET_RECONCILE_STABLE_N`),`ui_net_sink` 轮询 100 ms ——
|
||||
正常时序下消费者总是先 recv 到 EOF,对账抢不到。**只有 uiTask 被拖住**才可能出现,
|
||||
而那是设备内部状态。
|
||||
- 处置:按 Trap 25「不留未证明的复杂度」**删除该探针**;该场景登记为**残余验证项**,
|
||||
需设备内注入点(参照 `TEST_LATENCY_PROBE` 的编译开关模式)才能在真机复现。
|
||||
- 因此 P1 的**正确性依据**是:① 代码级论证(判据由边沿改电平、置位/清零完备、
|
||||
两处 relisten 补状态门);② 上表全量回归矩阵**不回归**;③ 不变量 I 的结构性论证。
|
||||
「抢先」的前瞻场景**未被真机证明**,如实标注,不冒充已验收。
|
||||
|
||||
**P1 落成状态(2026-10-12)**:代码已实现、`@build` 0 错 0 警(`Code=197096`,较基线 +12 B)、
|
||||
`mem-numbers` 快照已 `--write` 刷新、除下述基线问题外静态门禁全绿。
|
||||
⚠ **已知基线问题(非本改动引入)**:`doc-links` 在**任何从当前 `v2-on-ui` 切出的工作树**上都会报
|
||||
2 处失效引用——`RAM使用分析与优化方案.md:277/:585` → `scripts/ram_baseline.tsv`、
|
||||
`docs/内存管理/RAM预算台账.md`。这两个文件属另一在途任务、尚未提交,主工作树磁盘上有故主线
|
||||
门禁呈绿(见 `docs/环境与部署/并行任务工作树方案.md` §10.2)。待该任务合入后自动消解,
|
||||
**不应**由本分支代为提交他人半成品。
|
||||
2 处失效引用——`RAM使用分析与优化方案.md` 引用了两个**尚未提交**的文件(RAM 基线 `.tsv` 与
|
||||
RAM 预算台账 `.md`,属另一在途任务)。这两个文件在主工作树磁盘上存在故主线门禁呈绿,
|
||||
工作树里没有故必报红(机理见 `docs/环境与部署/并行任务工作树方案.md` §10.2)。
|
||||
待该任务合入后自动消解,**不应**由本分支代为提交他人半成品。
|
||||
|
||||
**P2(单一所有者)**
|
||||
- [ ] 新增 `net_listener_pump()`,与 `net_reconcile_tick` 同节拍,成为**唯一**调 `net_relisten_try` 的监听重建入口
|
||||
|
||||
Reference in New Issue
Block a user