fix(core): avoid blocking event loop during TUI PTY resize#34385
fix(core): avoid blocking event loop during TUI PTY resize#34385AgentEnder wants to merge 2 commits intomasterfrom
Conversation
✅ Deploy Preview for nx-dev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for nx-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
View your CI Pipeline Execution ↗ for commit 1e82495
☁️ Nx Cloud last updated this comment at |
8b9d228 to
6fc62fe
Compare
65a2868 to
f404353
Compare
🐳 We have a release for that!This PR has a release associated with it. You can try it out using this command: npx [email protected] my-workspaceOr just copy this version and use it in your own command: 22.5.0-pr.34385.f404353
To request a new release for this pull request, mention someone from the Nx team or the |
f404353 to
5b7aba4
Compare
| let mut state = state_arc.lock(); | ||
| if generation_arc.load(Ordering::SeqCst) != generation_at_dispatch { | ||
| state.processing = false; | ||
| return; | ||
| } |
There was a problem hiding this comment.
Race condition: when a resize supersedes the background scrollback processing, pending_lines contains lines wrapped at stale column widths but are not cleared. These invalid lines will be returned to the renderer on the next frame.
Impact: Terminal output will be rendered with incorrect wrapping, causing visual corruption until enough new output arrives to flush the stale buffer.
Fix: Clear the stale pending lines when a resize is detected:
let mut state = state_arc.lock();
if generation_arc.load(Ordering::SeqCst) != generation_at_dispatch {
state.pending_lines.clear();
state.bg_scrollback_cursor = 0;
state.processing = false;
return;
}| let mut state = state_arc.lock(); | |
| if generation_arc.load(Ordering::SeqCst) != generation_at_dispatch { | |
| state.processing = false; | |
| return; | |
| } | |
| let mut state = state_arc.lock(); | |
| if generation_arc.load(Ordering::SeqCst) != generation_at_dispatch { | |
| state.pending_lines.clear(); | |
| state.bg_scrollback_cursor = 0; | |
| state.processing = false; | |
| return; | |
| } | |
Spotted by Graphite Agent
Is this helpful? React 👍 or 👎 to let us know.
01eef4e to
124fc68
Compare
|
Failed to publish a PR release of this pull request, triggered by @AgentEnder. |
There was a problem hiding this comment.
Important
At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.
Nx Cloud has identified a possible root cause for your failed CI:
We classified this failure as environment_state rather than code_change. The error occurs in Vitest's worker pool IPC layer (write EPIPE) with MaxListenersExceededWarning, not in the modified TUI resize code paths. The 10.4% flakiness rate and npm-vs-pnpm inconsistency indicate test infrastructure cleanup issues rather than deterministic breakage from the async PTY changes.
No code changes were suggested for this issue.
🔂 A CI rerun has been triggered by adding an empty commit to this branch.
🎓 Learn more about Self-Healing CI on nx.dev
|
Failed to publish a PR release of this pull request, triggered by @AgentEnder. |
When switching from inline mode to full-screen TUI (or during window resize), the PTY resize operation reparsed ALL raw terminal output through a new vt100 parser synchronously on the event loop. For tasks with large output, this caused a noticeable hang. Add `resize_async()` which moves the expensive reparse to a background thread using a snapshot-and-replay pattern: 1. Quick snapshot of raw output (brief read lock) 2. Expensive reparse on background thread (no locks held) 3. Quick swap with replay of any new output (brief write lock) A generation counter prevents stale resizes from overwriting newer ones. Also combine two separate O(n) scrollback processing calls in inline mode into a single pass.
9c44ded to
1e82495
Compare
When switching from inline mode to full-screen TUI (or during window resize), the PTY resize operation reparsed ALL raw terminal output through a new vt100 parser synchronously on the event loop. For tasks with large output, this caused a noticeable hang.
Add
resize_async()which moves the expensive reparse to a background thread using a snapshot-and-replay pattern:A generation counter prevents stale resizes from overwriting newer ones.
Also combine two separate O(n) scrollback processing calls in inline mode into a single pass.