health: stop direct baileys probes
This commit is contained in:
@@ -4,23 +4,9 @@ import { info } from "../globals.js";
|
|||||||
import type { RuntimeEnv } from "../runtime.js";
|
import type { RuntimeEnv } from "../runtime.js";
|
||||||
import { makeProxyFetch } from "../telegram/proxy.js";
|
import { makeProxyFetch } from "../telegram/proxy.js";
|
||||||
import { resolveHeartbeatSeconds } from "../web/reconnect.js";
|
import { resolveHeartbeatSeconds } from "../web/reconnect.js";
|
||||||
import {
|
import { getWebAuthAgeMs, logWebSelfId, webAuthExists } from "../web/session.js";
|
||||||
createWaSocket,
|
|
||||||
getStatusCode,
|
|
||||||
getWebAuthAgeMs,
|
|
||||||
logWebSelfId,
|
|
||||||
waitForWaConnection,
|
|
||||||
webAuthExists,
|
|
||||||
} from "../web/session.js";
|
|
||||||
import { callGateway } from "../gateway/call.js";
|
import { callGateway } from "../gateway/call.js";
|
||||||
|
|
||||||
type HealthConnect = {
|
|
||||||
ok: boolean;
|
|
||||||
status?: number | null;
|
|
||||||
error?: string | null;
|
|
||||||
elapsedMs: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type TelegramProbe = {
|
type TelegramProbe = {
|
||||||
ok: boolean;
|
ok: boolean;
|
||||||
status?: number | null;
|
status?: number | null;
|
||||||
@@ -36,7 +22,6 @@ export type HealthSummary = {
|
|||||||
web: {
|
web: {
|
||||||
linked: boolean;
|
linked: boolean;
|
||||||
authAgeMs: number | null;
|
authAgeMs: number | null;
|
||||||
connect?: HealthConnect;
|
|
||||||
};
|
};
|
||||||
telegram: {
|
telegram: {
|
||||||
configured: boolean;
|
configured: boolean;
|
||||||
@@ -57,49 +42,6 @@ export type HealthSummary = {
|
|||||||
const DEFAULT_TIMEOUT_MS = 10_000;
|
const DEFAULT_TIMEOUT_MS = 10_000;
|
||||||
const TELEGRAM_API_BASE = "https://api.telegram.org";
|
const TELEGRAM_API_BASE = "https://api.telegram.org";
|
||||||
|
|
||||||
async function probeWebConnect(timeoutMs: number): Promise<HealthConnect> {
|
|
||||||
const started = Date.now();
|
|
||||||
const sock = await createWaSocket(false, false);
|
|
||||||
try {
|
|
||||||
await Promise.race([
|
|
||||||
waitForWaConnection(sock),
|
|
||||||
new Promise((_resolve, reject) =>
|
|
||||||
setTimeout(() => reject(new Error("timeout")), timeoutMs),
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
status: null,
|
|
||||||
error: null,
|
|
||||||
elapsedMs: Date.now() - started,
|
|
||||||
};
|
|
||||||
} catch (err) {
|
|
||||||
const status = getStatusCode(err);
|
|
||||||
// Conflict/duplicate sessions are expected when the primary gateway session
|
|
||||||
// is already connected. Treat these as healthy so health checks don’t flap.
|
|
||||||
if (status === 409 || status === 515) {
|
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
status,
|
|
||||||
error: "already connected (conflict)",
|
|
||||||
elapsedMs: Date.now() - started,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
ok: false,
|
|
||||||
status,
|
|
||||||
error: err instanceof Error ? err.message : String(err),
|
|
||||||
elapsedMs: Date.now() - started,
|
|
||||||
};
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
sock.ws?.close();
|
|
||||||
} catch {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchWithTimeout(
|
async function fetchWithTimeout(
|
||||||
url: string,
|
url: string,
|
||||||
timeoutMs: number,
|
timeoutMs: number,
|
||||||
@@ -189,7 +131,6 @@ async function probeTelegram(
|
|||||||
|
|
||||||
export async function getHealthSnapshot(
|
export async function getHealthSnapshot(
|
||||||
timeoutMs?: number,
|
timeoutMs?: number,
|
||||||
opts?: { probe?: boolean },
|
|
||||||
): Promise<HealthSummary> {
|
): Promise<HealthSummary> {
|
||||||
const cfg = loadConfig();
|
const cfg = loadConfig();
|
||||||
const linked = await webAuthExists();
|
const linked = await webAuthExists();
|
||||||
@@ -209,9 +150,6 @@ export async function getHealthSnapshot(
|
|||||||
|
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
const cappedTimeout = Math.max(1000, timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
const cappedTimeout = Math.max(1000, timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
||||||
const connect =
|
|
||||||
linked && opts?.probe ? await probeWebConnect(cappedTimeout) : undefined;
|
|
||||||
|
|
||||||
const telegramToken =
|
const telegramToken =
|
||||||
process.env.TELEGRAM_BOT_TOKEN ?? cfg.telegram?.botToken ?? "";
|
process.env.TELEGRAM_BOT_TOKEN ?? cfg.telegram?.botToken ?? "";
|
||||||
const telegramConfigured = telegramToken.trim().length > 0;
|
const telegramConfigured = telegramToken.trim().length > 0;
|
||||||
@@ -223,7 +161,7 @@ export async function getHealthSnapshot(
|
|||||||
const summary: HealthSummary = {
|
const summary: HealthSummary = {
|
||||||
ts: Date.now(),
|
ts: Date.now(),
|
||||||
durationMs: Date.now() - start,
|
durationMs: Date.now() - start,
|
||||||
web: { linked, authAgeMs, connect },
|
web: { linked, authAgeMs },
|
||||||
telegram: { configured: telegramConfigured, probe: telegramProbe },
|
telegram: { configured: telegramConfigured, probe: telegramProbe },
|
||||||
heartbeatSeconds,
|
heartbeatSeconds,
|
||||||
sessions: {
|
sessions: {
|
||||||
|
|||||||
@@ -218,12 +218,7 @@ export async function statusCommand(
|
|||||||
runtime.log(` ${line}`);
|
runtime.log(` ${line}`);
|
||||||
}
|
}
|
||||||
if (health) {
|
if (health) {
|
||||||
const waLine = health.web.connect
|
runtime.log(info("WA connect: reported by gateway (no direct probe)"));
|
||||||
? health.web.connect.ok
|
|
||||||
? info(`WA connect: ok (${health.web.connect.elapsedMs}ms)`)
|
|
||||||
: `WA connect: failed (${health.web.connect.status ?? "unknown"})${health.web.connect.error ? ` - ${health.web.connect.error}` : ""}`
|
|
||||||
: info("WA connect: skipped (not linked)");
|
|
||||||
runtime.log(waLine);
|
|
||||||
|
|
||||||
const tgLine = health.telegram.configured
|
const tgLine = health.telegram.configured
|
||||||
? health.telegram.probe?.ok
|
? health.telegram.probe?.ok
|
||||||
|
|||||||
@@ -701,7 +701,7 @@ export async function startGatewayServer(port = 18789): Promise<GatewayServer> {
|
|||||||
const cached = healthCache;
|
const cached = healthCache;
|
||||||
if (cached && now - cached.ts < HEALTH_REFRESH_INTERVAL_MS) {
|
if (cached && now - cached.ts < HEALTH_REFRESH_INTERVAL_MS) {
|
||||||
respond(true, cached, undefined, { cached: true });
|
respond(true, cached, undefined, { cached: true });
|
||||||
void refreshHealthSnapshot({ probe: true }).catch((err) =>
|
void refreshHealthSnapshot({ probe: false }).catch((err) =>
|
||||||
logError(
|
logError(
|
||||||
`background health refresh failed: ${formatError(err)}`,
|
`background health refresh failed: ${formatError(err)}`,
|
||||||
),
|
),
|
||||||
@@ -709,7 +709,7 @@ export async function startGatewayServer(port = 18789): Promise<GatewayServer> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const snap = await refreshHealthSnapshot({ probe: true });
|
const snap = await refreshHealthSnapshot({ probe: false });
|
||||||
respond(true, snap, undefined);
|
respond(true, snap, undefined);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
respond(
|
respond(
|
||||||
|
|||||||
Reference in New Issue
Block a user