eval: 第 1 轮检验脚本(跑、杀进程、导出去来历、盲评编号、Jev 三问、数字与过程)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import { appendFileSync, existsSync, readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
import type { ChildProcess } from "node:child_process";
|
||||
import { sleep } from "./study.ts";
|
||||
|
||||
// 账本里没有时间戳,墙钟时间由检验自己记:研究进程跑着的时候每隔一会儿看一眼账本,
|
||||
// 新出现的每条记录记下"第一次看到它的时刻",写成 timeline.jsonl(每行 {seq, kind, at},at 是毫秒)。
|
||||
// 只读打开账本、只查序号和种类,不经 Ledger.records()(那会每次重读、重查全部内容)。
|
||||
// 时刻比真实写入晚最多一个间隔,用来算阶段级的墙钟足够。
|
||||
|
||||
const POLL_MS = 1000;
|
||||
|
||||
export interface TimelineRow {
|
||||
seq: number;
|
||||
kind: string;
|
||||
at: number;
|
||||
}
|
||||
|
||||
/** 已经记下的最大序号;文件还没有就是 0。接着跑时往同一个文件后面追加。 */
|
||||
function lastSeq(file: string): number {
|
||||
if (!existsSync(file)) return 0;
|
||||
return readTimeline(file).reduce((m, r) => Math.max(m, r.seq), 0);
|
||||
}
|
||||
|
||||
/** 研究进程退出前一直记;进程退出后再看最后一眼。调用前要先等 waitForLedger(表建好了才能读)。 */
|
||||
export async function watchTimeline(studyDir: string, child: ChildProcess, file: string): Promise<void> {
|
||||
let seen = lastSeq(file);
|
||||
const look = () => {
|
||||
const db = new DatabaseSync(join(studyDir, "ledger.sqlite"), { readOnly: true });
|
||||
try {
|
||||
const rows = db.prepare("SELECT seq, kind FROM records WHERE seq > ? ORDER BY seq").all(seen) as Array<{ seq: number; kind: string }>;
|
||||
const at = Date.now();
|
||||
for (const r of rows) appendFileSync(file, `${JSON.stringify({ seq: r.seq, kind: r.kind, at })}\n`);
|
||||
if (rows.length > 0) seen = rows.at(-1)!.seq;
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
};
|
||||
while (child.exitCode === null && child.signalCode === null) {
|
||||
look();
|
||||
await sleep(POLL_MS);
|
||||
}
|
||||
look();
|
||||
}
|
||||
|
||||
export function readTimeline(file: string): TimelineRow[] {
|
||||
return readFileSync(file, "utf8")
|
||||
.split("\n")
|
||||
.filter((l) => l !== "")
|
||||
.map((l) => JSON.parse(l) as TimelineRow);
|
||||
}
|
||||
Reference in New Issue
Block a user