From 6c599d108181a741823ad9bb2c77b1e8c67e6d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=94=B3=E6=99=97?= Date: Tue, 28 Jul 2026 08:38:02 -0700 Subject: [PATCH] =?UTF-8?q?fix(pm2):=20=E7=BB=99=20pm2=20jlist=20=E8=BE=93?= =?UTF-8?q?=E5=87=BA=E6=8D=95=E8=8E=B7=E5=8A=A0=20maxBuffer=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=A7=20fleet=20=E4=B8=8B=20start-bot=20ENOBUFS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象:机器上 bot 数量较多时(实测 46 个 pm2 进程),dashboard/CLI 新建 bot 无法自动上线——`botmux start-bot ` 在第一步 `pm2 jlist` 就抛 `spawnSync ... ENOBUFS`,还没开始拉起进程就失败。 根因:`pm2 jlist` 会把每个进程的完整 env + 元数据序列化进 stdout,输出体积 随 bot 数近似线性增长;本机 jlist 已达 ~1.6 MB。而捕获它的两处 spawnSync (cli.ts `pm2Capture`、core/plugins/pm2.ts `capturePluginPm2`)都没设 maxBuffer,用的是 Node 默认 1 MiB 上限 → 超限即 ENOBUFS。阈值约 30 个进程, 本机早已越过。既有 bot 不受影响(daemon 冷启动/restart 走批量 pm2 start 路径),只有单条 start-bot 读 jlist 时中招,所以表现为“老 bot 正常、新建 bot 起不来”。 修复:两处捕获 jlist 的 spawnSync 都加 `maxBuffer: 64 * 1024 * 1024`,远高于 任何真实 fleet 规模。与仓库其它大输出捕获(ps `-axww` 32 MiB、 session-discovery 16 MiB)一致。 验证: - 复现:默认 maxBuffer 跑 `pm2 jlist`(1.6 MB)→ ENOBUFS;加 64 MiB → 正常 读全量。 - 修后 `node dist/cli.js start-bot <卡住的 appId> --json` → {"ok":true, "state":"started","processName":"botmux-45"},该 bot 真正上线(pm2 online)。 - pnpm build 绿;bot-live-control / plugin-pm2-env / pm2-command 15/15 全过。 Co-Authored-By: Riff --- src/cli.ts | 7 +++++++ src/core/plugins/pm2.ts | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/src/cli.ts b/src/cli.ts index 29a3e961e..02802d901 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -330,6 +330,13 @@ function pm2Capture(args: string[], home: string = PM2_HOME, timeoutMs = 10_000) env: pm2Env(home), shell: pm2.shell ?? false, timeout: timeoutMs, + // `pm2 jlist` serializes EVERY process's full env + metadata, so its stdout + // grows ~linearly with the bot count. Node's default spawnSync maxBuffer is + // 1 MiB — a box with ~30+ bots blows past it and spawnSync fails with + // ENOBUFS, which surfaced as `start-bot` (dashboard "bring one bot online") + // dying before it could launch anything. Lift the cap well above any real + // fleet size. (ps/git captures elsewhere already do the same.) + maxBuffer: 64 * 1024 * 1024, }); if (r.status !== 0) { const detail = r.error?.message diff --git a/src/core/plugins/pm2.ts b/src/core/plugins/pm2.ts index e87f1a74e..b62a30039 100644 --- a/src/core/plugins/pm2.ts +++ b/src/core/plugins/pm2.ts @@ -56,6 +56,10 @@ export function capturePluginPm2(args: string[], opts: { timeoutMs?: number; env env: pm2Env(opts.env), shell: pm2.shell ?? false, timeout: opts.timeoutMs ?? 10_000, + // `pm2 jlist` output scales with the process count (full env per process); + // Node's 1 MiB default spawnSync buffer overflows to ENOBUFS on large + // fleets. Match cli.ts pm2Capture — lift the cap far above any real size. + maxBuffer: 64 * 1024 * 1024, }); if (result.status !== 0) { const detail = result.error?.message