feat(cli): improve gateway status output
This commit is contained in:
@@ -32,6 +32,7 @@ export type GatewayClientOptions = {
|
||||
maxProtocol?: number;
|
||||
onEvent?: (evt: EventFrame) => void;
|
||||
onHelloOk?: (hello: HelloOk) => void;
|
||||
onConnectError?: (err: Error) => void;
|
||||
onClose?: (code: number, reason: string) => void;
|
||||
onGap?: (info: { expected: number; received: number }) => void;
|
||||
};
|
||||
@@ -130,6 +131,9 @@ export class GatewayClient {
|
||||
this.opts.onHelloOk?.(helloOk);
|
||||
})
|
||||
.catch((err) => {
|
||||
this.opts.onConnectError?.(
|
||||
err instanceof Error ? err : new Error(String(err)),
|
||||
);
|
||||
const msg = `gateway connect failed: ${String(err)}`;
|
||||
if (this.opts.mode === "probe") logDebug(msg);
|
||||
else logError(msg);
|
||||
|
||||
123
src/gateway/probe.ts
Normal file
123
src/gateway/probe.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
|
||||
import type { SystemPresence } from "../infra/system-presence.js";
|
||||
import { GatewayClient } from "./client.js";
|
||||
|
||||
export type GatewayProbeAuth = {
|
||||
token?: string;
|
||||
password?: string;
|
||||
};
|
||||
|
||||
export type GatewayProbeClose = {
|
||||
code: number;
|
||||
reason: string;
|
||||
hint?: string;
|
||||
};
|
||||
|
||||
export type GatewayProbeResult = {
|
||||
ok: boolean;
|
||||
url: string;
|
||||
connectLatencyMs: number | null;
|
||||
error: string | null;
|
||||
close: GatewayProbeClose | null;
|
||||
health: unknown;
|
||||
status: unknown;
|
||||
presence: SystemPresence[] | null;
|
||||
configSnapshot: unknown;
|
||||
};
|
||||
|
||||
function formatError(err: unknown): string {
|
||||
if (err instanceof Error) return err.message;
|
||||
return String(err);
|
||||
}
|
||||
|
||||
export async function probeGateway(opts: {
|
||||
url: string;
|
||||
auth?: GatewayProbeAuth;
|
||||
timeoutMs: number;
|
||||
}): Promise<GatewayProbeResult> {
|
||||
const startedAt = Date.now();
|
||||
const instanceId = randomUUID();
|
||||
let connectLatencyMs: number | null = null;
|
||||
let connectError: string | null = null;
|
||||
let close: GatewayProbeClose | null = null;
|
||||
|
||||
return await new Promise<GatewayProbeResult>((resolve) => {
|
||||
let settled = false;
|
||||
const settle = (result: Omit<GatewayProbeResult, "url">) => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
client.stop();
|
||||
resolve({ url: opts.url, ...result });
|
||||
};
|
||||
|
||||
const client = new GatewayClient({
|
||||
url: opts.url,
|
||||
token: opts.auth?.token,
|
||||
password: opts.auth?.password,
|
||||
clientName: "cli",
|
||||
clientVersion: "dev",
|
||||
mode: "probe",
|
||||
instanceId,
|
||||
onConnectError: (err) => {
|
||||
connectError = formatError(err);
|
||||
},
|
||||
onClose: (code, reason) => {
|
||||
close = { code, reason };
|
||||
},
|
||||
onHelloOk: async () => {
|
||||
connectLatencyMs = Date.now() - startedAt;
|
||||
try {
|
||||
const [health, status, presence, configSnapshot] = await Promise.all([
|
||||
client.request("health"),
|
||||
client.request("status"),
|
||||
client.request("system-presence"),
|
||||
client.request("config.get", {}),
|
||||
]);
|
||||
settle({
|
||||
ok: true,
|
||||
connectLatencyMs,
|
||||
error: null,
|
||||
close,
|
||||
health,
|
||||
status,
|
||||
presence: Array.isArray(presence)
|
||||
? (presence as SystemPresence[])
|
||||
: null,
|
||||
configSnapshot,
|
||||
});
|
||||
} catch (err) {
|
||||
settle({
|
||||
ok: false,
|
||||
connectLatencyMs,
|
||||
error: formatError(err),
|
||||
close,
|
||||
health: null,
|
||||
status: null,
|
||||
presence: null,
|
||||
configSnapshot: null,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const timer = setTimeout(
|
||||
() => {
|
||||
settle({
|
||||
ok: false,
|
||||
connectLatencyMs,
|
||||
error: connectError ? `connect failed: ${connectError}` : "timeout",
|
||||
close,
|
||||
health: null,
|
||||
status: null,
|
||||
presence: null,
|
||||
configSnapshot: null,
|
||||
});
|
||||
},
|
||||
Math.max(250, opts.timeoutMs),
|
||||
);
|
||||
|
||||
client.start();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user