Sharing a singleton Chromium CDP service across multiple OpenCrabs profiles #189
Replies: 2 comments 1 reply
-
|
@adolfousier maybe you would want to make the cdp-bridge a built-in solution. |
Beta Was this translation helpful? Give feedback.
-
|
Done. Added When set, the browser manager connects to an existing Chromium instance via CDP instead of spawning a new one. All profiles can share a single browser. Usage:
chromium --remote-debugging-port=9222 --headless --no-sandbox
[browser]
cdp_endpoint = "ws://localhost:9222"Results:
The browser manager now checks for Test added: 3783 tests pass, clippy clean. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
The Problem
OpenCrabs compiles browser tools (
browser_navigate,browser_click, etc.) into every profile binary via thebrowserfeature. Each tool relies on aBrowserManagerstruct that callschromiumoxide'sBrowser::launch()to spawn a headless Chromium instance directly over CDP — no intermediate scripts, no shared state. The struct is not a singleton: every profile carries its ownBrowserManager, and everyensure_browser()call spawns a fresh Chromium process on its own random debugging port (--remote-debugging-port=0).With 3 profiles (default, ops, family), any browser action triggered independent Chromium instances. A real measurement of the built-in tools on a 961 MB VDS showed:
No shared lifecycle, no crash recovery, no logging — each profile managed its own browser independently, with no coordination mechanism.
The Solution
A singleton Chromium service shared across all 3 profiles, controlled by a lightweight Python bridge (
/usr/local/bin/cdp-bridge).Architecture
chromium-cdp.service— systemd unit running one headless Chromium with CDP on port 9222cdp-bridge— Python script that checks the service is alive viasystemctl showand provides a clean WS interface for CDP commandsChromium flags used
Key flag:
--renderer-process-limit=1limits to one renderer process. (Memory-heavy--single-processwas unstable — crashed with SIGTRAP on this kernel.)Why not
chromiumoxide?We could have patched
chromiumoxideto use a shared port, but:Browser::launch()starts its own process — the Cargo featurebrowserembeds the full launch logic per binarysystemd hardening
Memory limits and crash protection added to
chromium-cdp.service:MemoryMaxMemoryHighRestartStartLimitBurstNoNewPrivilegesPrivateTmpProtectSystemProfile services
All 3 profiles (default, ops, family) run as user-level systemd units with
Wants=chromium-cdp.serviceandAfter=chromium-cdp.service— ensuring the Chromium singleton starts before any profile that needs it.Results
A full browsing session on rede-vest.ru (scrolling top to bottom, loading all content) was measured step by step:
cdp-bridge singleton (shared across 3 profiles):
Takeaways
--renderer-process-limit=1cuts memory ~40% without breaking page renderingBeta Was this translation helpful? Give feedback.
All reactions