Skip to content

perf(lsp): deduplicate concurrent identical diagnostic runs#24560

Draft
evilsamaritan wants to merge 5 commits into
oxc-project:mainfrom
evilsamaritan:pr/lsp-dedup-diagnostics
Draft

perf(lsp): deduplicate concurrent identical diagnostic runs#24560
evilsamaritan wants to merge 5 commits into
oxc-project:mainfrom
evilsamaritan:pr/lsp-dedup-diagnostics

Conversation

@evilsamaritan

@evilsamaritan evilsamaritan commented Jul 15, 2026

Copy link
Copy Markdown

🚧 Draft — stacked on #23768 and #23797 (@Sysix). Please don't merge until those land.

The first 4 commits are @Sysix's (included so the branch builds; GitHub shows them under his name). Only the last commit is mine. Once the stack lands I'll rebase onto main so this is a single commit, and un-draft.

Idea

After #23768 diagnostics run off-thread, so requests can overlap. From what I can see, a single save then triggers two full type-aware lints for the same (uri, version) — the server's on-save lint and the editor's Fix-All pull — which run at the same time and compete for CPU. In my testing on a large monorepo (IntelliJ, type-aware on), collapsing them into one run took roughly 25% off the Fix-All time on a big file.

What it does

A small per-worker registry of in-flight runs, keyed by URI. Requests for the same (uri, version) await one shared future instead of starting a second identical lint. Each run has a unique id and an RAII guard removes its entry on completion, cancellation, or panic (keyed by id, so a finishing run never deletes a newer entry that reused the same version). The onType/onSave gating moves to Tool predicates checked before this path, so the shared future always runs the full run_diagnostic. Passes cargo fmt and clippy (pedantic). A follow-up could add cancelling the older run when a newer version arrives.

IDE-side counterpart: oxc-project/oxc-intellij-plugin#542. Refs oxc-project/oxc-intellij-plugin#366.

Builds directly on your work, @Sysix — if you'd rather fold it into your stack yourself, that's completely fine by me.

Sysix and others added 5 commits July 14, 2026 13:14
In push mode a single save triggers two full type-aware lints: the server's
own on-save lint (did_save) and the editor's Fix-All warm-up diagnostic pull,
both for the same (uri, version). They run concurrently and contend for CPU.

Add a per-worker in-flight registry keyed by URI. Requests for the same
(uri, version) join a single Shared future instead of spawning a second
identical run. Each run carries a unique id, and an RAII guard removes its
entry on completion, cancellation, or panic — keyed by that id, so a
finishing run never deletes a newer entry that reused the same version. The
registry uses a std Mutex so the guard can clean up from Drop; its critical
sections are short and never await. The on-type/on-save gating moves to Tool
predicates checked before this path, so the shared future always runs the
full run_diagnostic and is never poisoned with a gated-empty result.

A newer version supersedes the entry; cancelling the superseded run itself
is left to a follow-up.
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.

2 participants