Skip to content

fix(cloakserve): evict poll()-alive but CDP-dead Chrome instead of 502ing (ADR-0163 stage 0) - #1

Merged
DivMode merged 1 commit into
mainfrom
fix/cloakserve-corpse-eviction
Aug 8, 2026
Merged

fix(cloakserve): evict poll()-alive but CDP-dead Chrome instead of 502ing (ADR-0163 stage 0)#1
DivMode merged 1 commit into
mainfrom
fix/cloakserve-corpse-eviction

Conversation

@DivMode

@DivMode DivMode commented Aug 8, 2026

Copy link
Copy Markdown
Owner

What

Fix the session_infra corpse race (ADR-0163 stage 0). During an olabrowser identity-lease rebuild, a client closes Chrome and immediately relaunches on the same fingerprint seed. Chrome tears down its DevTools/CDP socket seconds before the OS process exits, so process.poll() reports the corpse as alive and get_or_launch hands it back. handle_json_version then gets connection-refused on the CDP port and returned 502 without evicting the dead entry, so retry bursts kept hitting the same corpse.

Impact: the entire session_infra failure bucket, ~8% of scrapes. A 6h prod sample showed 3,241 dead-port 502s vs 3,243 warm "already running" hits — warm reuse across a rebuild failed ~100% of the time.

Fix

  • Root: get_or_launch probes the CDP port (a cheap 0.5s local TCP connect) before reusing a poll()-alive process; a corpse fails the probe and is evicted + relaunched.
  • Defense-in-depth: /json/version and /json/list evict + retry once on a connection error, so a process dying between the probe and the fetch becomes one cold relaunch instead of a persistent 502.
  • Eviction matches the pooled process by object identity, so a concurrent same-seed relaunch is never killed.

Tests

108 pass (6 new). Mutation-verified: reverting only the source makes 5 of the new tests fail.

Out of scope

The olabrowser-side retry backoff is a separate follow-on; this fix stands alone — the corpse now becomes a clean cold launch, so retries succeed.

…2ing (ADR-0163 stage 0)

During an olabrowser identity-lease rebuild, a client closes Chrome and immediately relaunches on the same fingerprint seed. Chrome tears down its DevTools/CDP socket seconds before the OS process exits, so process.poll() reports the corpse as alive and get_or_launch hands it back; handle_json_version then gets connection-refused on the CDP port and returned 502 WITHOUT evicting, so retry bursts kept hitting the same corpse. This is the entire session_infra failure bucket (~8% of scrapes; a 6h prod sample showed 3,241 dead-port 502s vs 3,243 warm 'already running' hits — ~100% warm-reuse failure across a rebuild).

get_or_launch now probes the CDP port (a cheap 0.5s local TCP connect) before reusing a poll()-alive process, evicting and relaunching a corpse. The /json/version and /json/list handlers evict + retry once on a connection error as defense-in-depth. Eviction matches the pooled process by object identity, so a concurrent same-seed relaunch is never killed. 108 tests pass (6 new, mutation-verified).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@DivMode
DivMode merged commit e7ac36a into main Aug 8, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant