Skip to content

fix(stalls): a starved disk no longer freezes main or the window (core 0.40.8) - #228

Merged
Maxaubert merged 1 commit into
mainfrom
fix/async-writes
Oct 15, 2026
Merged

Maxaubert merged 1 commit into
mainfrom
fix/async-writes

Conversation

@Maxaubert

Copy link
Copy Markdown
Owner

Owner, 2026-10-15: "gotten some heavy stalls ... up to 5-10 seconds", then "go ahead" on this fix.

Measured in Stable's diag log, 11:48:49 to 11:53:45: the disk was starved machine-wide (the fs canary 1 to 7 s in both Stable and Prism; the cause was Prism's bundled search indexer crawling C: after its service crashed, which the Prism session is fixing). Stable's main stalled 3 to 6 s with no IPC around it, its page 6 to 8.7 s (stacks in onKey); Prism's main barely stalled.

Why Stable froze: main saved tabs.json (about every 400 ms while agents work) and the window state with writeFileSync, and a Ctrl+V read the clipboard with sendSync, so the page waited on a blocked main.

Changes

  • createAtomicWriter (core): debounced saves write their .tmp on the threadpool and rename on main. The close, quit and session end still write synchronously (rule 7). A save never lands over a newer one.
  • tabsStore and windowState use it.
  • Paste reads the clipboard through ipc.invoke (readClipboardAsync); the key handler still returns at once. The sync channel stays for a host bridge without the async one. Pastes are still sanitised (rule 1).
  • The diag log was already async (only its crash/quit flush is sync), unchanged.

Tests: 4 new unit tests for the writer (async save lands, newest of a burst wins, an older save never lands over the close's, a later save does). Unit 2141 pass. Full e2e: all scenarios passed (a first run had one 45 s prompt timeout that did not repeat).

Core 0.40.7 -> 0.40.8, app 0.52.2 -> 0.52.3. Prism gets the async paste through the core; its own periodic saves could use createAtomicWriter too.

🤖 Generated with Claude Code

https://claude.ai/code/session_017XYVRPzvhLpPCr75uB6uaA

…e 0.40.8)

Owner, 2026-10-15: "heavy stalls ... up to 5-10 seconds". MEASURED in
Stable's diag log, 11:48:49 to 11:53:45: the disk was starved machine-wide
(the fs canary 1 to 7 s in Stable and Prism alike; Prism's bundled search
indexer crawling C:), and Stable's main stalled 3 to 6 s with no IPC around
it while Prism's barely did. Main wrote tabs.json (every ~400 ms while agents
work) and the window state with writeFileSync, and a Ctrl+V asked main for
the clipboard with sendSync, so the page froze 6 to 8 s with main (page
stacks in onKey).

- createAtomicWriter (core/main/atomicWrite.ts): the debounced saves write
  their .tmp on the threadpool and rename on main; the close, quit and
  session end still write synchronously (rule 7). A save never lands over a
  newer one.
- tabsStore and windowState use it.
- The paste reads the clipboard through ipc.invoke (readClipboardAsync); the
  key handler still returns at once. The sync channel stays for a host
  bridge without the async one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017XYVRPzvhLpPCr75uB6uaA
@Maxaubert
Maxaubert merged commit d7aa221 into main Oct 15, 2026
2 checks passed
github-actions Bot pushed a commit that referenced this pull request Oct 15, 2026
…e 0.40.8) (#228)

Owner, 2026-10-15: "heavy stalls ... up to 5-10 seconds". MEASURED in
Stable's diag log, 11:48:49 to 11:53:45: the disk was starved machine-wide
(the fs canary 1 to 7 s in Stable and Prism alike; Prism's bundled search
indexer crawling C:), and Stable's main stalled 3 to 6 s with no IPC around
it while Prism's barely did. Main wrote tabs.json (every ~400 ms while agents
work) and the window state with writeFileSync, and a Ctrl+V asked main for
the clipboard with sendSync, so the page froze 6 to 8 s with main (page
stacks in onKey).

- createAtomicWriter (core/main/atomicWrite.ts): the debounced saves write
  their .tmp on the threadpool and rename on main; the close, quit and
  session end still write synchronously (rule 7). A save never lands over a
  newer one.
- tabsStore and windowState use it.
- The paste reads the clipboard through ipc.invoke (readClipboardAsync); the
  key handler still returns at once. The sync channel stays for a host
  bridge without the async one.


Claude-Session: https://claude.ai/code/session_017XYVRPzvhLpPCr75uB6uaA

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@Maxaubert
Maxaubert deleted the fix/async-writes branch October 15, 2026 10:33
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