mslxdff 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/mslxdff.js +73 -26
- package/package.json +1 -1
package/bin/mslxdff.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execFile } from "node:child_process";
|
|
3
|
-
import { readFileSync, existsSync, statSync } from "node:fs";
|
|
3
|
+
import { readFileSync, existsSync, statSync, rmSync } from "node:fs";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { dirname, join, basename } from "node:path";
|
|
6
6
|
import { startServer, resolvePort } from "../src/server.js";
|
|
7
|
-
import { DEFAULT_PORT } from "../src/state.js";
|
|
7
|
+
import { DEFAULT_PORT, defaultStateFile } from "../src/state.js";
|
|
8
8
|
import { createRouter } from "../src/routes.js";
|
|
9
9
|
import { createUpstreamClient } from "../src/upstream.js";
|
|
10
10
|
import { createModelsService } from "../src/models.js";
|
|
@@ -54,6 +54,37 @@ if (args.includes("-stop") || args.includes("--stop")) {
|
|
|
54
54
|
process.exit(0);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
if (args.includes("-uninstall") || args.includes("--uninstall")) {
|
|
58
|
+
const { stopped, pid } = stopDaemon();
|
|
59
|
+
if (stopped) console.log(`mslxdff daemon stopped (pid ${pid})`);
|
|
60
|
+
else console.log("mslxdff daemon not running");
|
|
61
|
+
|
|
62
|
+
const stateFile = defaultStateFile();
|
|
63
|
+
const dir = dirname(stateFile);
|
|
64
|
+
const removed = [];
|
|
65
|
+
for (const f of [
|
|
66
|
+
stateFile,
|
|
67
|
+
pidFile(),
|
|
68
|
+
logFile(),
|
|
69
|
+
join(dir, "calls.log"),
|
|
70
|
+
join(dir, "errors.log"),
|
|
71
|
+
join(dir, "events.log"),
|
|
72
|
+
]) {
|
|
73
|
+
try {
|
|
74
|
+
rmSync(f, { force: true });
|
|
75
|
+
removed.push(f);
|
|
76
|
+
} catch {
|
|
77
|
+
// already gone, fine
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (removed.length) console.log(`removed ${removed.length} file(s):\n ${removed.join("\n ")}`);
|
|
81
|
+
else console.log("no state/log files to remove");
|
|
82
|
+
|
|
83
|
+
console.log("\npackage still installed — finish with:");
|
|
84
|
+
console.log(" npm uninstall -g mslxdff");
|
|
85
|
+
process.exit(0);
|
|
86
|
+
}
|
|
87
|
+
|
|
57
88
|
if (args.includes("-status") || args.includes("--status") || args.includes("-s")) {
|
|
58
89
|
await printStatus();
|
|
59
90
|
process.exit(0);
|
|
@@ -196,33 +227,48 @@ if (groupCmd && groupCmd !== "create") {
|
|
|
196
227
|
const removed = peers.removeByGroup(a);
|
|
197
228
|
console.log(before ? `left group "${a}" (${removed} member(s) removed)` : `not a member of group "${a}"`);
|
|
198
229
|
} else if (action === "list") {
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
if (names.length) {
|
|
202
|
-
for (const n of names) {
|
|
203
|
-
console.log(`${n} (${Object.keys(all[n].members || {}).length} members)`);
|
|
204
|
-
// probe every member endpoint concurrently to show reachability + latency
|
|
205
|
-
const probes = Object.entries(all[n].members || {}).map(([id, m]) => ({
|
|
206
|
-
id, url: m?.url,
|
|
207
|
-
}));
|
|
208
|
-
const joined = loadGroupsJoined().find((g) => g.name === n);
|
|
209
|
-
if (joined?.leaderUrl) probes.push({ id: "leader", url: joined.leaderUrl });
|
|
210
|
-
const results = await Promise.all(probes.map(probeHealth));
|
|
211
|
-
const rows = results.sort((a, b) => (a.rank ?? 9) - (b.rank ?? 9));
|
|
212
|
-
for (const r of rows) {
|
|
213
|
-
const state = r.fail ? `fail ${r.fail}` : `ok ${r.ms}ms`;
|
|
214
|
-
const label = r.id && r.id !== r.url ? r.id + " " : "";
|
|
215
|
-
console.log(` ${label}${r.url} ${state}`);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
} else {
|
|
230
|
+
const joinedList = loadGroupsJoined();
|
|
231
|
+
if (!joinedList.length) {
|
|
219
232
|
console.log("no groups on this node");
|
|
233
|
+
process.exit(0);
|
|
220
234
|
}
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
235
|
+
const { token } = await loadToken();
|
|
236
|
+
const fetchImpl = (url, opts) => fetch(url, { ...opts, signal: AbortSignal.timeout(1500) });
|
|
237
|
+
for (const g of joinedList) {
|
|
238
|
+
const isLeader = !g.leaderUrl;
|
|
239
|
+
let members;
|
|
240
|
+
if (isLeader) {
|
|
241
|
+
members = groups.list()[g.name]?.members || {};
|
|
242
|
+
} else {
|
|
243
|
+
try {
|
|
244
|
+
members = await refreshGroupMembers(g.name, {
|
|
245
|
+
leaderUrl: g.leaderUrl,
|
|
246
|
+
memberName: g.memberName,
|
|
247
|
+
url: g.myUrl,
|
|
248
|
+
token,
|
|
249
|
+
fetchImpl,
|
|
250
|
+
});
|
|
251
|
+
} catch (err) {
|
|
252
|
+
console.log(`${g.name} (members unavailable — leader unreachable: ${errMsg(err)})`);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
console.log(`${g.name} (${Object.keys(members).length} members)`);
|
|
257
|
+
// probe every member endpoint concurrently for reachability + latency
|
|
258
|
+
const probes = Object.entries(members).map(([id, m]) => ({ id, url: m?.url || id }));
|
|
259
|
+
if (!isLeader && g.leaderUrl && !probes.some((p) => p.url === g.leaderUrl)) {
|
|
260
|
+
probes.push({ id: "leader", url: g.leaderUrl });
|
|
261
|
+
}
|
|
262
|
+
const results = await Promise.all(probes.map(probeHealth));
|
|
263
|
+
const rows = results.sort((a, b) => (a.rank ?? 9) - (b.rank ?? 9));
|
|
264
|
+
for (const r of rows) {
|
|
265
|
+
const state = r.fail ? `fail ${r.fail}` : `ok ${r.ms}ms`;
|
|
266
|
+
const label = r.id && r.id !== r.url ? r.id + " " : "";
|
|
267
|
+
console.log(` ${label}${r.url} ${state}`);
|
|
268
|
+
}
|
|
225
269
|
}
|
|
270
|
+
console.log(`\njoined groups (${joinedList.length}):`);
|
|
271
|
+
for (const g of joinedList) console.log(` ${g.name} ${g.leaderUrl || "(this node is the leader)"}`);
|
|
226
272
|
} else {
|
|
227
273
|
console.error("usage: mslxdff -creategroup <name> | -group sync | -group leave <name> | -group list");
|
|
228
274
|
}
|
|
@@ -589,6 +635,7 @@ Usage:
|
|
|
589
635
|
mslxdff -model refresh force-refresh the model cache from the upstream
|
|
590
636
|
mslxdff -debug live-follow the daemon event stream (requests, errors, peer forwards)
|
|
591
637
|
mslxdff -stop stop the running daemon
|
|
638
|
+
mslxdff -uninstall stop the daemon and delete all state/log files
|
|
592
639
|
mslxdff -port N persist the listen port (restarts the daemon on it if running)
|
|
593
640
|
mslxdff -update update mslxdff to the latest published version
|
|
594
641
|
mslxdff -showtoken print the current auth token
|