mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-20 14:30:57 +00:00
fix(gateway): increase WS handshake timeout from 3s to 10s (#49262)
* fix(gateway): increase WS handshake timeout from 3s to 10s The 3-second default is too aggressive when the event loop is under load (concurrent sessions, compaction, agent turns), causing spurious 'gateway closed (1000)' errors on CLI commands like `openclaw cron list`. Changes: - Increase DEFAULT_HANDSHAKE_TIMEOUT_MS from 3_000 to 10_000 - Add OPENCLAW_HANDSHAKE_TIMEOUT_MS env var for user override (no VITEST gate) - Keep OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS as fallback for existing tests Fixes #46892 * fix: restore VITEST guard on test env var, use || for empty-string fallback, fix formatting * fix: cover gateway handshake timeout env override (#49262) (thanks @fuller-stack-dev) --------- Co-authored-by: Wilfred <wilfred@Wilfreds-Mac-mini.local> Co-authored-by: Ayaan Zaidi <hi@obviy.us>
This commit is contained in:
@@ -118,6 +118,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Slack/startup: harden `@slack/bolt` import interop across current bundled runtime shapes so Slack monitors no longer crash with `App is not a constructor` after plugin-sdk bundling changes. (#45953) Thanks @merc1305.
|
||||
- Windows/gateway status: accept `schtasks` `Last Result` output as an alias for `Last Run Result`, so running scheduled-task installs no longer show `Runtime: unknown`. (#47844) Thanks @MoerAI.
|
||||
- ACP/acpx: resolve the bundled plugin root from the actual plugin directory so plugin-local installs stay under `dist/extensions/acpx` instead of escaping to `dist/extensions` and failing runtime setup. (#47601) Thanks @ngutman.
|
||||
- Gateway/WS handshake: raise the default pre-auth handshake timeout to 10 seconds and add `OPENCLAW_HANDSHAKE_TIMEOUT_MS` as a runtime override so busy local gateways stop dropping healthy CLI connections at 3 seconds. (#49262) Thanks @fuller-stack-dev.
|
||||
- Gateway/websocket pairing bypass for disabled auth: skip device-pairing enforcement for Control UI operator sessions when `gateway.auth.mode=none`, so reverse-proxied dashboards no longer get stuck on `pairing required` despite auth being explicitly disabled. (#47148) Thanks @ademczuk.
|
||||
- Control UI/model switching: preserve the selected provider prefix when switching models from the chat dropdown, so multi-provider setups no longer send `anthropic/gpt-5.2`-style mismatches when the user picked `openai/gpt-5.2`. (#47581) Thanks @chrishham.
|
||||
- Control UI/storage: scope persisted settings keys by gateway base path, with migration from the legacy shared key, so multiple gateways under one domain stop overwriting each other's dashboard preferences. (#47932) Thanks @bobBot-claw.
|
||||
|
||||
@@ -21,10 +21,14 @@ export const __setMaxChatHistoryMessagesBytesForTest = (value?: number) => {
|
||||
maxChatHistoryMessagesBytes = value;
|
||||
}
|
||||
};
|
||||
export const DEFAULT_HANDSHAKE_TIMEOUT_MS = 3_000;
|
||||
export const DEFAULT_HANDSHAKE_TIMEOUT_MS = 10_000;
|
||||
export const getHandshakeTimeoutMs = () => {
|
||||
if (process.env.VITEST && process.env.OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS) {
|
||||
const parsed = Number(process.env.OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS);
|
||||
// User-facing env var (works in all environments); test-only var gated behind VITEST
|
||||
const envKey =
|
||||
process.env.OPENCLAW_HANDSHAKE_TIMEOUT_MS ||
|
||||
(process.env.VITEST && process.env.OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS);
|
||||
if (envKey) {
|
||||
const parsed = Number(envKey);
|
||||
if (Number.isFinite(parsed) && parsed > 0) {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
@@ -93,6 +93,29 @@ export function registerDefaultAuthTokenSuite(): void {
|
||||
}
|
||||
});
|
||||
|
||||
test("prefers OPENCLAW_HANDSHAKE_TIMEOUT_MS and falls back on empty string", () => {
|
||||
const prevHandshakeTimeout = process.env.OPENCLAW_HANDSHAKE_TIMEOUT_MS;
|
||||
const prevTestHandshakeTimeout = process.env.OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS;
|
||||
process.env.OPENCLAW_HANDSHAKE_TIMEOUT_MS = "75";
|
||||
process.env.OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS = "20";
|
||||
try {
|
||||
expect(getHandshakeTimeoutMs()).toBe(75);
|
||||
process.env.OPENCLAW_HANDSHAKE_TIMEOUT_MS = "";
|
||||
expect(getHandshakeTimeoutMs()).toBe(20);
|
||||
} finally {
|
||||
if (prevHandshakeTimeout === undefined) {
|
||||
delete process.env.OPENCLAW_HANDSHAKE_TIMEOUT_MS;
|
||||
} else {
|
||||
process.env.OPENCLAW_HANDSHAKE_TIMEOUT_MS = prevHandshakeTimeout;
|
||||
}
|
||||
if (prevTestHandshakeTimeout === undefined) {
|
||||
delete process.env.OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS;
|
||||
} else {
|
||||
process.env.OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS = prevTestHandshakeTimeout;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("connect (req) handshake returns hello-ok payload", async () => {
|
||||
const { STATE_DIR, createConfigIO } = await import("../config/config.js");
|
||||
const ws = await openWs(port);
|
||||
|
||||
Reference in New Issue
Block a user