Telegram: harden network retries and config
Co-authored-by: techboss <techboss@users.noreply.github.com>
This commit is contained in:
committed by
Gustavo Madeira Santana
parent
e43f4c0628
commit
b861a0bd73
@@ -1,19 +1,36 @@
|
||||
import { setDefaultAutoSelectFamily } from "net";
|
||||
import * as net from "node:net";
|
||||
import { resolveFetch } from "../infra/fetch.js";
|
||||
import type { TelegramNetworkConfig } from "../config/types.telegram.js";
|
||||
import { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
import { resolveTelegramAutoSelectFamilyDecision } from "./network-config.js";
|
||||
|
||||
// Workaround for Node.js 22 "Happy Eyeballs" (autoSelectFamily) bug
|
||||
// that causes intermittent ETIMEDOUT errors when connecting to Telegram's
|
||||
// dual-stack servers. Disabling autoSelectFamily forces sequential IPv4/IPv6
|
||||
// attempts which works reliably.
|
||||
let appliedAutoSelectFamily: boolean | null = null;
|
||||
const log = createSubsystemLogger("telegram/network");
|
||||
|
||||
// Node 22 workaround: disable autoSelectFamily to avoid Happy Eyeballs timeouts.
|
||||
// See: https://github.com/nodejs/node/issues/54359
|
||||
try {
|
||||
setDefaultAutoSelectFamily(false);
|
||||
} catch {
|
||||
// Ignore if not available (older Node versions)
|
||||
function applyTelegramNetworkWorkarounds(network?: TelegramNetworkConfig): void {
|
||||
const decision = resolveTelegramAutoSelectFamilyDecision({ network });
|
||||
if (decision.value === null || decision.value === appliedAutoSelectFamily) return;
|
||||
appliedAutoSelectFamily = decision.value;
|
||||
|
||||
if (typeof net.setDefaultAutoSelectFamily === "function") {
|
||||
try {
|
||||
net.setDefaultAutoSelectFamily(decision.value);
|
||||
const label = decision.source ? ` (${decision.source})` : "";
|
||||
log.info(`telegram: autoSelectFamily=${decision.value}${label}`);
|
||||
} catch {
|
||||
// ignore if unsupported by the runtime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prefer wrapped fetch when available to normalize AbortSignal across runtimes.
|
||||
export function resolveTelegramFetch(proxyFetch?: typeof fetch): typeof fetch | undefined {
|
||||
export function resolveTelegramFetch(
|
||||
proxyFetch?: typeof fetch,
|
||||
options?: { network?: TelegramNetworkConfig },
|
||||
): typeof fetch | undefined {
|
||||
applyTelegramNetworkWorkarounds(options?.network);
|
||||
if (proxyFetch) return resolveFetch(proxyFetch);
|
||||
const fetchImpl = resolveFetch();
|
||||
if (!fetchImpl) {
|
||||
|
||||
Reference in New Issue
Block a user