mslxdff 0.1.15 → 0.1.17
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 +28 -0
- package/package.json +1 -1
package/bin/mslxdff.js
CHANGED
|
@@ -200,6 +200,18 @@ if (groupCmd && groupCmd !== "create") {
|
|
|
200
200
|
if (names.length) {
|
|
201
201
|
for (const n of names) {
|
|
202
202
|
console.log(`${n} (${Object.keys(all[n].members || {}).length} members)`);
|
|
203
|
+
// probe every member endpoint concurrently to show reachability + latency
|
|
204
|
+
const probes = Object.entries(all[n].members || {}).map(([id, m]) => ({
|
|
205
|
+
id, url: m?.url,
|
|
206
|
+
}));
|
|
207
|
+
const joined = loadGroupsJoined().find((g) => g.name === n);
|
|
208
|
+
if (joined?.leaderUrl) probes.push({ id: "leader", url: joined.leaderUrl });
|
|
209
|
+
const results = await Promise.all(probes.map(probeHealth));
|
|
210
|
+
const rows = results.sort((a, b) => (a.rank ?? 9) - (b.rank ?? 9));
|
|
211
|
+
for (const r of rows) {
|
|
212
|
+
const state = r.fail ? `fail ${r.fail}` : `ok ${r.ms}ms`;
|
|
213
|
+
console.log(` ${String(r.id || "?")} ${r.url} ${state}`);
|
|
214
|
+
}
|
|
203
215
|
}
|
|
204
216
|
} else {
|
|
205
217
|
console.log("no groups on this node");
|
|
@@ -273,6 +285,22 @@ function markJoined(entry) {
|
|
|
273
285
|
|
|
274
286
|
function errMsg(err) { return String(err?.message || err); }
|
|
275
287
|
|
|
288
|
+
// Probe a member's health endpoint concurrently (v1/health preferred,
|
|
289
|
+
// falling back to /health). Returns { id, url, ms, rank } or { id, url, fail }.
|
|
290
|
+
const HEALTH_TIMEOUT_MS = 4000;
|
|
291
|
+
async function probeHealth({ id, url } = {}) {
|
|
292
|
+
if (!url) return { id, url, fail: "no url", rank: 3 };
|
|
293
|
+
const base = String(url).replace(/\/+$/, "");
|
|
294
|
+
const startedAt = Date.now();
|
|
295
|
+
try {
|
|
296
|
+
const res = await fetch(`${base}/health`, { signal: AbortSignal.timeout(HEALTH_TIMEOUT_MS) });
|
|
297
|
+
if (!res.ok) return { id, url: base, fail: `HTTP ${res.status}`, rank: 2 };
|
|
298
|
+
return { id, url: base, ms: Date.now() - startedAt, rank: 0 };
|
|
299
|
+
} catch {
|
|
300
|
+
return { id, url: base, fail: "unreachable", rank: 2 };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
276
304
|
function readModelsCache(cacheFile) {
|
|
277
305
|
try {
|
|
278
306
|
return JSON.parse(readFileSync(cacheFile, "utf8"));
|