Skip to content

fix(lsp): prevent socket deadlock on large files with incremental sync#16538

Open
JayZenith wants to merge 1 commit intoanomalyco:devfrom
JayZenith:fix/lsp-incremental-sync-ts
Open

fix(lsp): prevent socket deadlock on large files with incremental sync#16538
JayZenith wants to merge 1 commit intoanomalyco:devfrom
JayZenith:fix/lsp-incremental-sync-ts

Conversation

@JayZenith
Copy link

@JayZenith JayZenith commented Mar 8, 2026

Issue for this PR

Closes #16115

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Patching large Python files (e.g. server_args.py in sglang, ~255KB) causes opencode to hang indefinitely on "Preparing patch...".

textDocument/didOpen and textDocument/didChange both sent the full file content over a Unix domain socket. At 255KB this overflows the ~213KB kernel socket buffer. When pyright is CPU-saturated on its initial project scan it can't drain the socket fast enough, both sides stall waiting on each other. Deadlock.

Two changes:

  1. All LSP notifications are now fire-and-forget. Node.js buffers the write internally and streams to pyright as the socket drains, without blocking opencode.
  2. didChange sends a line-level incremental diff instead of the full document, so subsequent patches never re-saturate the buffer.

How did you verify your code works?

Profiled both the official nightlyand this fix simultaneously using ss -xp to observe Unix socket buffer states.

Official nightly on server_args.py inside sglang:
Recv-Q: 219,461 -> pyright's buffer, not draining
Send-Q: 224,000 -> opencode blocked on write, pyright at 108% CPU.

This fix under the same conditions:
Recv-Q: 561 -> draining normally
Send-Q: 0 ->opencode not blocked
Two back-to-back patches on server_args.py completed without hanging.

Screenshots / recordings

N/A

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Track open file content to compute line-level diffs for didChange,
avoiding full-document resends on every edit. Fire all notifications
without awaiting so writes stream to the LSP server without blocking
on a saturated socket buffer.
@github-actions github-actions bot added the needs:compliance This means the issue will auto-close after 2 hours. label Mar 8, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

The following comment was made by an LLM, it may be inaccurate:

Found 1 potentially related PR:

#16114: fix(lsp): timeout write to prevent hang when LSP server stdin is full

This PR appears to be addressing a related issue (socket buffer saturation causing hangs) but uses a different approach (write timeouts). Since PR #16538 (the current PR) closes issue #16115 and provides a more comprehensive fix with incremental diffs and fire-and-forget notifications, #16114 may be an earlier attempt or alternative solution to the same underlying problem.

@github-actions github-actions bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Mar 8, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@JayZenith
Copy link
Author

@thdxr found this while working on sglang, took a while to track down but the socket profiling made it pretty clear what was happening. lmk if you have any questions.

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.

UI freezes indefinitely when patching large Python files in large projects

1 participant