Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4e31acb

Browse files
garrytanclaude
andcommitted
fix: auto-clear stale heartbeat when process is dead
Add PID to heartbeat file. eval-watch checks process.kill(pid, 0) and auto-deletes the heartbeat when the PID is no longer alive — no manual cleanup needed after crashed/killed E2E runs. Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent 43fbe16 commit 4e31acb

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

scripts/eval-watch.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const STALE_THRESHOLD_SEC = 600; // 10 minutes
1919

2020
export interface HeartbeatData {
2121
runId: string;
22+
pid?: number;
2223
startedAt: string;
2324
currentTest: string;
2425
status: string;
@@ -51,6 +52,16 @@ function readJSON<T>(filePath: string): T | null {
5152
}
5253
}
5354

55+
/** Check if a process is alive (signal 0 = existence check, doesn't kill). */
56+
function isProcessAlive(pid: number): boolean {
57+
try {
58+
process.kill(pid, 0);
59+
return true;
60+
} catch {
61+
return false;
62+
}
63+
}
64+
5465
/** Format seconds as Xm Ys */
5566
function formatDuration(sec: number): string {
5667
if (sec < 60) return `${sec}s`;
@@ -127,9 +138,17 @@ if (import.meta.main) {
127138
const showTail = process.argv.includes('--tail');
128139

129140
const render = () => {
130-
const heartbeat = readJSON<HeartbeatData>(HEARTBEAT_PATH);
141+
let heartbeat = readJSON<HeartbeatData>(HEARTBEAT_PATH);
131142
const partial = readJSON<PartialData>(PARTIAL_PATH);
132143

144+
// Auto-clear heartbeat if the process is dead
145+
if (heartbeat?.pid && !isProcessAlive(heartbeat.pid)) {
146+
try { fs.unlinkSync(HEARTBEAT_PATH); } catch { /* already gone */ }
147+
process.stdout.write('\x1B[2J\x1B[H');
148+
process.stdout.write(`Cleared stale heartbeat — PID ${heartbeat.pid} is no longer running.\n\n`);
149+
heartbeat = null;
150+
}
151+
133152
// Clear screen
134153
process.stdout.write('\x1B[2J\x1B[H');
135154
process.stdout.write(renderDashboard(heartbeat, partial) + '\n');

test/helpers/session-runner.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ export async function runSkillTest(options: {
216216
const toolDesc = `${item.name}(${truncate(JSON.stringify(item.input || {}), 60)})`;
217217
atomicWriteSync(HEARTBEAT_PATH, JSON.stringify({
218218
runId,
219+
pid: proc.pid,
219220
startedAt,
220221
currentTest: testName,
221222
status: 'running',

0 commit comments

Comments
 (0)