Fix: schedule idle prune so cached dashboard WebViews are evicted - #1386
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 10, 2026, 7:30 AM ET / 11:30 UTC. Summary Reproducibility: yes. Current source has no timer after release, and the isolated runtime harness provides high-confidence process-level evidence that scheduled eviction resolves the retained helper processes. Review metrics: 2 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Next step before merge
Security Review detailsBest possible solution: Merge the generation-guarded earliest-deadline scheduler after required checks, retaining the autonomous and multi-entry deadline regression coverage. Do we have a high-confidence way to reproduce the issue? Yes. Current source has no timer after release, and the isolated runtime harness provides high-confidence process-level evidence that scheduled eviction resolves the retained helper processes. Is this the best way to solve the issue? Yes. Scheduling one main-actor timer for the earliest idle deadline directly enforces the existing timeout contract without introducing per-entry timer complexity or postponing older entries. AGENTS.md: found and applied where relevant. Codex review notes: reasoning high; reviewed against 7c0ed036e2e6. Label changesLabel changes:
Label justifications:
Evidence reviewedWhat I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a05be04f48
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| /// which can be an hour away on slow refresh cadences — leaving the hidden WebKit | ||
| /// helper processes (WebContent/GPU/Networking) resident the whole time. | ||
| private func scheduleIdlePrune() { | ||
| self.idlePruneWorkItem?.cancel() |
There was a problem hiding this comment.
Keep the earlier idle-prune timer armed
When multiple dashboard caches are released within the idle window, canceling the single global work item here lets a later release postpone eviction of an older idle entry. For example, if store A is released at t=0 and store B at t=50s, the t=61s prune for A is canceled and the next no-activity prune is scheduled for about t=111s, so A's WebView/WebKit helpers survive almost another minute past the intended 60s timeout. Please schedule against the earliest pending expiration or keep per-entry timers so older entries are still pruned on time.
Useful? React with 👍 / 👎.
The webview cache evicts entries idle longer than 60s, but prune() only ran on the next acquire/release. With an hourly refresh cadence the hidden ChatGPT WebView - and its WebContent (~500MB), GPU and Networking helper processes - stayed resident for the whole hour, effectively permanently. Schedule a prune after each release so eviction happens at the idle timeout the comment already promises. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
a05be04 to
779c4d1
Compare
|
Rebased onto current Runtime proof used an isolated nonpersistent Local proof: 17 focused tests, @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Inspectable runtime proof from the isolated nonpersistent The harness process remained alive through 30 seconds. The injected cache timeout was 0.2 seconds; WebKit performed its own delayed helper teardown after cache eviction. No provider auth, browser cookies, or Keychain access was used. @clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. Re-review progress:
|
|
Landed in Proof:
No provider auth, browser cookies, or Keychain access was used for runtime validation. |
Problem
OpenAIDashboardWebViewCacheintends to keep the offscreen dashboard WebView alive for only 60s (idleTimeout, with a comment noting long-lived hidden ChatGPT tabs are expensive). Butprune()is only invoked on the next acquire/release or preserved-page expiry — there is no timer that fires after the idle window. With the default hourly refresh cadence, the WebView released after a scrape is never pruned until the next refresh acquires it again.Net effect: the WebKit helper processes stay resident essentially permanently. Measured on an M-series MacBook (CodexBar 0.32.6, Codex provider with web usage source): after each refresh, a
com.apple.WebKit.WebContentprocess (~500MB RSS) plus GPU and Networking helpers (~75MB) survive the full hour between refreshes, instead of 60 seconds.Fix
Schedule pruning for the earliest nonbusy cache entry's idle deadline. Each timer reschedules after pruning so independently released entries retain their own deadlines, and a generation guard prevents canceled/stale work items from mutating current timer state.
The idle timeout is injected through the cache initializer for focused tests. Regression coverage verifies eviction without later cache activity and verifies that a later release does not postpone an older idle entry.
Testing
swift test --filter OpenAIDashboardWebViewCacheTests- 17 tests passed.make check- SwiftFormat and strict SwiftLint clean.swift test- 3,432 tests in 394 suites passed.WKWebsiteDataStoreloadingabout:blank, without provider auth, cookies, or Keychain access. New WebContent/GPU/Networking helper PIDs appeared; WebContent exited about 2 seconds after the test idle prune, and GPU/Networking exited about 8 seconds after appearance while the harness process remained alive.autoreview --mode branch --base origin/main- clean, confidence 0.94.🤖 Generated with Claude Code