browser: skip throwaway WebSocket probes for wss:// cloud CDP profiles

For cloud browser providers like Browser Use and Browserbase, each raw
WebSocket health check provisions a new ephemeral browser session. Check
the cached Playwright connection state instead, which reflects whether
we actually have an active connection without side effects.
This commit is contained in:
ShawnPana 2026-03-10 20:38:48 -07:00
parent 4cb24d8263
commit db2993ca92
2 changed files with 18 additions and 0 deletions

View File

@ -119,6 +119,13 @@ const MAX_NETWORK_REQUESTS = 500;
const cachedByCdpUrl = new Map<string, ConnectedBrowser>();
const connectingByCdpUrl = new Map<string, Promise<ConnectedBrowser>>();
/**
* Returns true if there is an active cached Playwright connection for the given CDP URL.
*/
export function hasActivePlaywrightConnection(cdpUrl: string): boolean {
return cachedByCdpUrl.has(cdpUrl.replace(/\/$/, ""));
}
function normalizeCdpUrl(raw: string) {
return raw.replace(/\/$/, "");
}

View File

@ -3,6 +3,7 @@ import {
PROFILE_POST_RESTART_WS_TIMEOUT_MS,
resolveCdpReachabilityTimeouts,
} from "./cdp-timeouts.js";
import { isWebSocketUrl } from "./cdp.helpers.js";
import {
isChromeCdpReady,
isChromeReachable,
@ -16,6 +17,7 @@ import {
stopChromeExtensionRelayServer,
} from "./extension-relay.js";
import { getBrowserProfileCapabilities } from "./profile-capabilities.js";
import { hasActivePlaywrightConnection } from "./pw-session.js";
import {
CDP_READY_AFTER_LAUNCH_MAX_TIMEOUT_MS,
CDP_READY_AFTER_LAUNCH_MIN_TIMEOUT_MS,
@ -60,11 +62,20 @@ export function createProfileAvailability({
});
const isReachable = async (timeoutMs?: number) => {
// For direct WebSocket endpoints (e.g. Browser Use), each raw CDP health check
// opens a new WebSocket which may provision a new browser session. Check the
// cached Playwright connection instead — it reflects the actual connection state.
if (isWebSocketUrl(profile.cdpUrl)) {
return hasActivePlaywrightConnection(profile.cdpUrl);
}
const { httpTimeoutMs, wsTimeoutMs } = resolveTimeouts(timeoutMs);
return await isChromeCdpReady(profile.cdpUrl, httpTimeoutMs, wsTimeoutMs);
};
const isHttpReachable = async (timeoutMs?: number) => {
if (isWebSocketUrl(profile.cdpUrl)) {
return hasActivePlaywrightConnection(profile.cdpUrl);
}
const { httpTimeoutMs } = resolveTimeouts(timeoutMs);
return await isChromeReachable(profile.cdpUrl, httpTimeoutMs);
};