mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-02 13:11:38 +00:00
52 lines
1.7 KiB
TypeScript
52 lines
1.7 KiB
TypeScript
import fs from "node:fs";
|
|
import { pathToFileURL } from "node:url";
|
|
import { createVerifiedSqliteSnapshot } from "../../src/infra/sqlite-snapshot.js";
|
|
|
|
type PublicationCrashPoint = "after-publish" | "before-publish";
|
|
|
|
const SLEEP_BUFFER = new Int32Array(new SharedArrayBuffer(4));
|
|
|
|
function parseCrashPoint(value: string | undefined): PublicationCrashPoint {
|
|
if (value === "after-publish" || value === "before-publish") {
|
|
return value;
|
|
}
|
|
throw new Error(`invalid SQLite publication crash point: ${String(value)}`);
|
|
}
|
|
|
|
function holdAtCrashPoint(markerPath: string, crashPoint: PublicationCrashPoint): never {
|
|
const marker = fs.openSync(markerPath, "wx", 0o600);
|
|
try {
|
|
fs.writeFileSync(marker, `${crashPoint}\n`);
|
|
fs.fsyncSync(marker);
|
|
} finally {
|
|
fs.closeSync(marker);
|
|
}
|
|
while (true) {
|
|
Atomics.wait(SLEEP_BUFFER, 0, 0, 60_000);
|
|
}
|
|
}
|
|
|
|
async function main(argv: string[]): Promise<void> {
|
|
const crashPoint = parseCrashPoint(argv[0]);
|
|
const sourcePath = argv[1];
|
|
const targetPath = argv[2];
|
|
const markerPath = argv[3];
|
|
if (!sourcePath || !targetPath || !markerPath) {
|
|
throw new Error("SQLite publication worker requires source, target, and marker paths.");
|
|
}
|
|
|
|
await createVerifiedSqliteSnapshot({
|
|
sourcePath,
|
|
targetPath,
|
|
beforePublish:
|
|
crashPoint === "before-publish" ? () => holdAtCrashPoint(markerPath, crashPoint) : undefined,
|
|
afterPublish:
|
|
crashPoint === "after-publish" ? () => holdAtCrashPoint(markerPath, crashPoint) : undefined,
|
|
});
|
|
throw new Error(`SQLite publication worker passed ${crashPoint} without being terminated.`);
|
|
}
|
|
|
|
if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
|
|
await main(process.argv.slice(2));
|
|
}
|