mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-03 17:10:23 +00:00
* fix: import CHANNEL_IDS from leaf module to avoid TDZ on init (#48832) schema.ts and validation.ts imported CHANNEL_IDS from channels/registry.js, which re-exports from channels/ids.js but also imports plugins/runtime.js. When the bundler resolves this dependency graph, the re-exported CHANNEL_IDS can be undefined at the point config/validation.ts evaluates (temporal dead zone), causing 'CHANNEL_IDS is not iterable' on startup. Fix: import CHANNEL_IDS directly from channels/ids.js (the leaf module with zero heavy dependencies) and normalizeChatChannelId from channels/chat-meta.js. Fixes #48832 * fix: improve WS handshake reliability on slow-startup environments (#48736) On Windows with large dist bundles (46MB/639 files), heavy synchronous module loading blocks the event loop during CLI startup, preventing timely processing of the connect.challenge frame and causing ~80% handshake timeout failures. Changes: - Yield event loop (setImmediate) before starting WS connection in callGateway to let pending I/O drain after heavy module loading - Add OPENCLAW_CONNECT_CHALLENGE_TIMEOUT_MS env var override for client-side connect challenge timeout (server already has OPENCLAW_HANDSHAKE_TIMEOUT_MS) - Include diagnostic timing in challenge timeout error messages (elapsed vs limit) for easier debugging - Add tests for env var override and resolution logic --------- Co-authored-by: Brad Groux <bradgroux@users.noreply.github.com>
47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
export const DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS = 10_000;
|
|
export const MIN_CONNECT_CHALLENGE_TIMEOUT_MS = 250;
|
|
export const MAX_CONNECT_CHALLENGE_TIMEOUT_MS = DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS;
|
|
|
|
export function clampConnectChallengeTimeoutMs(timeoutMs: number): number {
|
|
return Math.max(
|
|
MIN_CONNECT_CHALLENGE_TIMEOUT_MS,
|
|
Math.min(MAX_CONNECT_CHALLENGE_TIMEOUT_MS, timeoutMs),
|
|
);
|
|
}
|
|
|
|
export function getConnectChallengeTimeoutMsFromEnv(
|
|
env: NodeJS.ProcessEnv = process.env,
|
|
): number | undefined {
|
|
const raw = env.OPENCLAW_CONNECT_CHALLENGE_TIMEOUT_MS;
|
|
if (raw) {
|
|
const parsed = Number(raw);
|
|
if (Number.isFinite(parsed) && parsed > 0) {
|
|
return parsed;
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
export function resolveConnectChallengeTimeoutMs(timeoutMs?: number | null): number {
|
|
if (typeof timeoutMs === "number" && Number.isFinite(timeoutMs)) {
|
|
return clampConnectChallengeTimeoutMs(timeoutMs);
|
|
}
|
|
const envOverride = getConnectChallengeTimeoutMsFromEnv();
|
|
if (envOverride !== undefined) {
|
|
return clampConnectChallengeTimeoutMs(envOverride);
|
|
}
|
|
return DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS;
|
|
}
|
|
|
|
export function getPreauthHandshakeTimeoutMsFromEnv(env: NodeJS.ProcessEnv = process.env): number {
|
|
const configuredTimeout =
|
|
env.OPENCLAW_HANDSHAKE_TIMEOUT_MS || (env.VITEST && env.OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS);
|
|
if (configuredTimeout) {
|
|
const parsed = Number(configuredTimeout);
|
|
if (Number.isFinite(parsed) && parsed > 0) {
|
|
return parsed;
|
|
}
|
|
}
|
|
return DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS;
|
|
}
|