-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdaemon.mjs
More file actions
76 lines (70 loc) · 1.96 KB
/
Copy pathdaemon.mjs
File metadata and controls
76 lines (70 loc) · 1.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { spawn } from "node:child_process";
import net from "node:net";
import os from "node:os";
import path from "node:path";
import fs from "node:fs";
export function resolveDaemon() {
if (process.env.HERMESMQD_PATH) return process.env.HERMESMQD_PATH;
const exe = process.platform === "win32" ? "hermesmqd.exe" : "hermesmqd";
for (const dir of ["debug", "release"]) {
const candidate = path.resolve("..", "hermesmq", "target", dir, exe);
if (fs.existsSync(candidate)) return candidate;
}
return "hermesmqd";
}
async function waitReachable(addr, timeoutMs) {
const [host, port] = addr.split(":");
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const ok = await new Promise((resolve) => {
const sock = net.connect({ host, port: Number(port) });
sock.once("connect", () => {
sock.destroy();
resolve(true);
});
sock.once("error", () => resolve(false));
});
if (ok) return;
await new Promise((r) => setTimeout(r, 100));
}
throw new Error(`daemon not reachable at ${addr} within ${timeoutMs}ms`);
}
export async function startDaemon({ nodeId = 1, clientAddr, peerAddr }) {
const dataDir = fs.mkdtempSync(path.join(os.tmpdir(), "hermesmq-js-"));
const daemon = spawn(
resolveDaemon(),
[
"--node-id",
String(nodeId),
"--data-dir",
dataDir,
"--client-addr",
clientAddr,
"--peer-addr",
peerAddr,
],
{ stdio: "ignore" },
);
const cleanup = () =>
fs.rmSync(dataDir, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 });
const stop = () =>
new Promise((resolve) => {
if (daemon.exitCode !== null) {
cleanup();
resolve();
return;
}
daemon.once("exit", () => {
cleanup();
resolve();
});
daemon.kill();
});
try {
await waitReachable(clientAddr, 10_000);
} catch (e) {
await stop();
throw e;
}
return { stop };
}