Skip to content

Fix tab leak: add closure timeout and reaper recovery for stuck tabs - #39

Open
hamsterkacke wants to merge 1 commit into
mandatoryprogrammer:mainfrom
hamsterkacke:fix/tab-closure-timeout-and-reaper-recovery
Open

Fix tab leak: add closure timeout and reaper recovery for stuck tabs#39
hamsterkacke wants to merge 1 commit into
mandatoryprogrammer:mainfrom
hamsterkacke:fix/tab-closure-timeout-and-reaper-recovery

Conversation

@hamsterkacke

Copy link
Copy Markdown

Problem

Tabs can become permanently leaked when CDP WebSocket calls hang during closure (dead connection, Chrome overloaded, etc.). When this happens:

  1. perform_tab_closure blocks indefinitely on a CDP call with no timeout
  2. tab_info.closing stays true forever since the function never returns
  3. The reaper sweep unconditionally skips tabs with closing = true, so it can never clean them up

The tab stays open in Chrome permanently — both the normal close path and the reaper are defeated.

Fix

Three changes in cdp.js, designed as defense-in-depth:

  • Closure timeout (15s): perform_tab_closure is wrapped with Promise.race so hangs trigger the existing retry logic instead of blocking forever
  • Stale closure detection (30s): The reaper now tracks closing_since and resets stuck closures so they become eligible for force-close on the next sweep
  • Conditional reference cleanup: tab_info.browser/tab_info.tab are only nullified on successful closure, preserving the primary close method for retries

Tab closures could hang indefinitely when CDP WebSocket calls stall
(dead connection, Chrome overloaded), leaving tabs permanently stuck
with closing=true. The reaper sweep unconditionally skipped these tabs,
so they were never cleaned up.

Three fixes:
- Wrap perform_tab_closure with a 15s timeout so hangs trigger the
  existing retry logic instead of blocking forever
- Track closing_since timestamp; reaper resets stuck closures after 30s
  so they become eligible for force-close on the next sweep
- Only nullify browser/tab references on successful closure so retries
  can still use the primary close path
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