diff --git a/packages/conversation/src/shim.mjs b/packages/conversation/src/shim.mjs index 2adbe48b..d51c4a1f 100644 --- a/packages/conversation/src/shim.mjs +++ b/packages/conversation/src/shim.mjs @@ -22,7 +22,7 @@ // `populated 0`. A missing or unreadable file is unavailable, never empty. import { spawn } from "node:child_process"; -import { closeSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs"; +import { appendFileSync, closeSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs"; import { createServer } from "node:net"; import { join } from "node:path"; import { LineSplitter, encodeLine, parseLine } from "./framing.mjs"; @@ -136,6 +136,7 @@ async function handle(req) { if (startOf(pid) !== startTicks) continue; try { process.kill(pid, "SIGTERM"); + if (process.env.DW_TRACE) appendFileSync(process.env.DW_TRACE, JSON.stringify({ t: Date.now(), ev: 'term', pid }) + '\n'); signalled.push(pid); } catch { // gone already diff --git a/packages/conversation/tests/fake-pi.mjs b/packages/conversation/tests/fake-pi.mjs index b3014f86..f30f5a4c 100644 --- a/packages/conversation/tests/fake-pi.mjs +++ b/packages/conversation/tests/fake-pi.mjs @@ -615,13 +615,16 @@ const children = []; // K2); `forkLoop` forks every 5 ms (K12); `ignoreTerm` survives SIGTERM, so // only the kill phase ends it (K3, K10, K11). With `pidLog`, the fork loop // appends each child's pid and a `term` line when it gets SIGTERM (K12). +import * as __fs from 'node:fs'; +const require0 = () => __fs; function spawnChild({ setsid = false, forkLoop = false, ignoreTerm = false, pidLog = null } = {}) { const note = pidLog ? `const note=(s)=>require('node:fs').appendFileSync(${JSON.stringify(pidLog)},s+'\\n');` : "const note=()=>{};"; - const code = note + (ignoreTerm ? "process.on('SIGTERM',()=>note('term'));" : "") + (forkLoop + const code = note + (ignoreTerm ? "process.on('SIGTERM',()=>note('term'));" + (process.env.DW_TRACE ? `require('node:fs').appendFileSync(${JSON.stringify(process.env.DW_TRACE)},JSON.stringify({t:Date.now(),ev:'ready',pid:process.pid})+'\\n');` : "") : "") + (forkLoop ? "const {spawn}=require('node:child_process');setInterval(()=>{try{const c=spawn('sleep',['1000'],{stdio:'ignore'});if(c.pid)note(String(c.pid))}catch{}},5);setInterval(()=>{},1e9)" : "setInterval(()=>{},1e9)"); const child = spawn(process.execPath, ["-e", code], { stdio: "ignore", detached: setsid }); children.push(child.pid); + if (process.env.DW_TRACE) { require0().appendFileSync(process.env.DW_TRACE, JSON.stringify({ t: Date.now(), ev: 'spawn', pid: child.pid, ignoreTerm, setsid }) + '\n'); child.on('exit', (code, sig) => require0().appendFileSync(process.env.DW_TRACE, JSON.stringify({ t: Date.now(), ev: 'child-exit', pid: child.pid, code, sig }) + '\n')); } return child.pid; }