chore(工作区): 第 36 棒续作收口(A2 实例进程内面达成 · A8 改判)

- 拍板①「A」:实例一直在跑(实时视图 running@20001);进程内 /mcn/api/accounts 200 · total:5
  ⇒ A2 实例进程内面达成。纠正上一棒:其判「stopped」所据 PG dsh_instances.status 是滞后失真
- 拍板②「worker 用插件更新机制」:机制已落地且在跑(agent POST /shared-layer/pull + 定时轮询)
  真机对账快照 w-106 @23:52:11:stale:[mcn-suite] + failed:[timeout]
  ⇒ 106 自主拉取成立、该件拉取超时失败 ⇒ A8 由「未取证」改判为「机制在跑 · 该件超时」
- 平台侧问题(拉取超时 / 台账滞后)只报告不改码
- 收尾:R4 临时会话 DELETED=1 / POC_LEFT=0;未启动未停止任何实例
This commit is contained in:
admin committed 2026-09-26 00:36:34 +08:00
1 parent 6ece092782
commit df876aec90
4 files changed
+145

No files matched your search

+25
View File
@@ -933,3 +933,28 @@ try { socket.write(textFrame(text)); return true } // 🔴 返回值被丢弃
### 一句话
**群聊今天就能用(走 443 中继),端口是可选优化**;容量上连接层已能撑 10k 在线;**最该动的不是扩容,而是补扇出背压控制**。产出 ⇒ `交付物/端口与容量瓶颈评估-20260925.md`。⛔ 零代码改动、未部署、未 commit/push、未登记下一棒。
---
## 第 36 棒 · 续作(2026-09-26 00:17–00:4x)· 会话 `p36b-exec-plugin-dataline` · 用户两条拍板落地
### 拍板① =「A」⇒ A2 实例进程内面 ✅ 达成
- 🔴 **纠正上一棒**:实例**一直在跑**(实时视图 `GET /api/admin/users/<uid>/dsh/status` ⇒ `running:true`、`port:20001`);上一棒判「`stopped`」所据的是 **PG `dsh_instances.status`(滞后失真)**。⛔ 本棒**未启动/未停止**任何实例(`launch` 因 folder 口径返回 `bad_path`,无副作用)。
- **进程内读数**:`curl -s --compressed -H "Cookie: dsh_token=<实例 token>" http://127.0.0.1:20001/mcn/api/accounts` ⇒ **200** + **13,155 B** 正文 `{"ok":true,"total":5,"page":1,…,"account_name":"王微斯",…}`;无凭据访问实例根 ⇒ `401 dsh web authentication required`(证明 20001 = 该用户实例 Web)。
- R4 收尾:`DELETE FROM sessions WHERE user_agent='poc-curl2'` ⇒ `DELETED=1`、`POC_LEFT=0`。
### 拍板② =「worker 应该使用插件更新机制」(⛔ 不是给 106 开 ssh 通道)⇒ 机制已落地且在跑
- 源码实证(⛔ 未改一行):worker agent `POST /shared-layer/pull`(带 agent token,`src/worker/agent.ts:812`)+ **启动即拉一次 + 定时轮询**(`:816-819`);注释原话「**`restart dshs-worker` 就等于完成一次共享层同步,⛔ 不必再手工 scp**」;形态 = **节点主动拉(pull)+ 主节点对账告知**(`business-plugins.ts:373-377`),快照落 `<sharedRoot>/.node-sync-reports.json`。
- **真机对账快照**(309 B,`at` ⇒ 2026-09-25 23:52:11 CST,在我 23:22 `share 0.5.1` 之后):`w-106` · `authoritative:4` · `missing:[]` · **`stale:["dsh-plugin-mcn-suite"]`** · **`failed:[{"flat":"dsh-plugin-mcn-suite","error":"The operation was aborted due to timeout"}]`**。
- **判定**:**用户判断成立** —— 106 在自主拉取,不是「没通道」;但**该件拉取超时失败** ⇒ 106 仍为旧版。🔴 **平台侧参数/实现问题**(2.0 MB 包跨云拉取超时)⇒ **只报告不改码**(修复方向:调大超时 / 分块续拉 / 失败退避重试)。
- **A8 改判**:⛔「未取证」⇒ 🟡「**机制在跑 · 该件拉取超时失败(原因码具名)**」。
### 🔴 另一条平台侧发现(值得单独立项)
**`dsh_instances.status` 与实时视图不一致**(台账 `stopped`/`port:null`,实为 `running`@20001)⇒ **它影响一切「实例是否在跑」的判断**(本棒已因此差点误判)。
### 🧰 本机运维坑(本续作实测 · ⏳ 待写进 PLAYBOOK)
1. **`UID` 是 bash 只读内建变量** —— `UID=cce6…` 会报 `readonly variable` 且**赋值静默失败** ⇒ 后续 `curl http://127.0.0.1:$PORT/` 变成 `http://127.0.0.1:/`(**打到 nginx 上,返回 nginx 的 404**,极易误判成"应用没这个路由")。⇒ 变量名避开 `UID`。
2. **`.mjs` 里不能用 `require`**(须 `.cjs`);且**探针的 `catch` 分支必须 `process.exit()`** —— 否则 pg 连接不关,**进程永久挂住**(本续作实测两次 `RC=124`)⇒ 这才是此前「node 探针挂住」的真因,**不是**连接泄漏、更不是 `find` 慢。
3. **响应可能是 gzip** —— `curl` 不加 `--compressed` 时正文是二进制,`grep` 只报 `Binary file matches`、`head -c` 看起来"没输出" ⇒ 取 JSON 一律 `--compressed`。
4. **平台 Web 端口 = `127.0.0.1:3080`**(`dshs.service` MainPID 持有;另持有 `25022–25063` relay dial pool);`20001` 是**该用户实例**端口、`18081` 是 centrifugo、`20001` 之外的 `20001` 无…… ⛔ 别把实例端口当平台端口(本续作实测:对 `20001` 调平台路由得到实例的 `401 unauthorized`)。
@@ -13,3 +13,40 @@
- **收尾**:R10 `ROOT_OWNED_COUNT=0`;R4 临时会话 `DELETED=5`/`POC_LEFT=0`;47 `/tmp/p36*` 清零;本线域锁已释放;本 automation 置 `PAUSED`;⛔ 未登记第 37 棒(撞待拍板 2 项)。
- **交付件**:`$WS/交付物/MCN数据面接入-阶段二-切档与收口-20260925.md`;入口 `§0`/`§2` + `05-交接单/README.md §一` 已更新。
- **教训(下棒必看)**:① `node -e` 的 pg 探针会挂住并泄漏连接(累积 5 个后连 connect 都挂)⇒ 探针一律写独立 `.mjs`,收尾 `pkill -9 -f 'node -e'` 复核归零。② `pkill -f` 命中自身命令行会自杀 ⇒ 用字符类或走 `bash -s` 脚本。③ `dataPlaneConfig()` 无缓存 ⇒ **切档运行时立即生效、不需要重启**。④ 实例 home 目录名 = 带连字符 UUID,属主用户名 = 去连字符。
## 收尾实测(本棒闭环完成 · 2026-09-26 00:0x)
| 项 | 读数 |
|---|---|
| 提交① | `6aa8811` `chore(工作区): 插件投放与分库线收口入库(第 36 棒 · 三表切 platform)`(4 files, +596 −1) |
| 提交② | `6ece092` `chore(交付件): 第 36 棒收口补记(提交 6aa8811 / 推送 / 对账 0 0 / 域锁释放口径)` |
| 推送 | `318430c..6aa8811` / `6aa8811..6ece092` → `origin/master`(`rc=0`) |
| 对账 | `git rev-list --left-right --count origin/master...HEAD` = **`0 0`**;`HEAD = ORIGIN = 6ece092` |
| 禁止项自查 | `FORBIDDEN_CLEAN`(无 `tmp/`、无 `_tmp_seq*`、无 `05-交接单/` 下单子) |
| 域锁释放 | `ME="p36-exec-plugin-dataline" … --release-exec` ⇒ `✓ 已释放域锁(p36-exec-plugin-dataline)`(rc=0,目录已删) |
| 发布锁释放 | ⚠️ **首次不带 `ME=` 被拒**(`✗ 拒绝释放发布锁:未指定会话名` rc=1)⇒ 补 `ME=` 后 `✓ 已释放发布锁(归属已核:p36-exec-plugin-dataline)`(rc=0;`.locks/.publish` 目录已删) |
| ⛔ 未纳入提交 | `.workbuddy/memory/MEMORY.md`(diff **全为他线记忆瘦身**)+ `CODEBUDDY.md`/`state.py`/`.codebuddy/rules/server-ops.md`/`接续入口_IM线_20260922.md`/多个 `?? 交付物/…` —— **均他线在途,本棒未触碰** |
| 本 automation | **本次执行末置 `PAUSED`**;⛔ **未登记第 37 棒**(撞待拍板 2 项:A2 实例进程面 / 106 同步窗口) |
### ⚠️ 新发现(下棒必看)
- 🔴 **释放类命令一律要 `ME=`** —— 实测 `--release-exec` 与 `--release-publish` **都**要求 `ME="<会话名>"`;漏了 ⇒ **fail-closed 拒绝**(`rc=1`,⛔ 不是静默通过)。`--release-skeleton` 同理。
- ⚠️ **一个棒可能需要两次提交** —— 交付件里要写「提交 sha」时无法自指 ⇒ 先按读数提交一次、再补记一次(两次都 push)。
## 续作(2026-09-26 00:17–00:4x · 会话 `p36b-exec-plugin-dataline`)· 用户两条拍板落地
用户回话:**①「A」**(授权启动实例取进程内读数)**②「worker 应该使用插件更新机制」**(⛔ 不是给 106 开 ssh 通道)。
| 项 | 结果 |
|---|---|
| **A2 实例进程内面** | ✅ **达成** —— 实时视图 `running:true`@`20001`(🔴 **纠正上一棒**:其判「`stopped`」所据 PG `dsh_instances.status` 是**滞后失真**)。`curl --compressed -H "Cookie: dsh_token=<实例 token>" http://127.0.0.1:20001/mcn/api/accounts` ⇒ **200** + 13,155 B(`total:5`,与影子读 `hot_accounts 5=5` 一致)。⛔ 本棒**未启动/未停止**任何实例 |
| **A8(106)** | 🟡 **改判** —— 机制**已落地且在跑**(worker `POST /shared-layer/pull` + 启动即拉 + 定时轮询;注释原话「`restart dshs-worker` 就等于完成一次共享层同步」)。真机对账快照 `.node-sync-reports.json`:`w-106` @**23:52:11 CST**(我 23:22 share 之后)`authoritative:4` · `missing:[]` · **`stale:["dsh-plugin-mcn-suite"]`** · **`failed:[{"flat":"dsh-plugin-mcn-suite","error":"The operation was aborted due to timeout"}]`** ⇒ **自主拉取成立、该件拉取超时失败** ⇒ 106 仍旧版。🔴 **平台侧问题,只报告不改码** |
| **平台侧发现** | 🔴 **`dsh_instances.status` 与实时视图不一致**(台账 `stopped`/实为 `running`)⇒ 影响一切「实例是否在跑」的判断 ⇒ 值得单独立项 |
| R4 收尾 | `DELETE … user_agent='poc-curl2'` ⇒ `DELETED=1`、`POC_LEFT=0` |
### 🔴 本续作新增的四个坑(⏳ 待写进 PLAYBOOK)
1. **`UID` 是 bash 只读内建变量** —— 赋值静默失败 ⇒ `$PORT` 变空 ⇒ `curl http://127.0.0.1:/…` **打到 nginx**(返回 nginx 404,极易误判成"应用没这路由")。
2. **`.mjs` 不能用 `require`(改 `.cjs`)+ 探针 `catch` 必须 `process.exit()`** —— 否则 pg 连接不关、**进程永久挂住**(实测 `RC=124`)⇒ **这才是「node 探针挂住」的真因**,不是连接泄漏、更不是 `find` 慢。
3. **响应是 gzip** —— 不加 `--compressed` 时 `grep` 只报 `Binary file matches`、"看起来没输出" ⇒ 取 JSON 一律 `--compressed`。
4. **端口口径**:平台 Web = `127.0.0.1:3080`;`20001` = **该用户实例**;`18081` = centrifugo;`25022–25063` = relay dial pool ⇒ ⛔ 别把实例端口当平台端口。