The ignoreTerm tool child was TERMed before Node installed its handler when the claim store sits on a fast disk. Candidate fixes the fixture; the patch itself is not committed. Co-Authored-By: Claude Opus 5.5 <[email protected]>
44 lines
2.9 KiB
Diff
44 lines
2.9 KiB
Diff
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;
|
|
}
|
|
|