Skip to content

perf(workspace): stop stale diagnostics, lint code actions and completions early - #961

Closed
psteinroe wants to merge 1 commit into
test/editor-walk-edit-churnfrom
perf/cancel-analysis
Closed

psteinroe wants to merge 1 commit into
test/editor-walk-edit-churnfrom
perf/cancel-analysis

Conversation

@psteinroe

Copy link
Copy Markdown
Collaborator

Stacked on #957.

#954 made cancelled hover, inlay hint and semantic token requests stop their walk. Two follow-ups were left: whether cancellation reaches the server the way editors actually run it, and diagnostics, lint code actions and completions, which always ran to the end.

How editors run the server: cancellation already reaches it

  • The VS Code extension (postgres-language-server-vscode, src/session.ts) starts the binary with lsp-proxy. So do nvim-lspconfig's postgres_lsp (cmd = { 'postgres-language-server', 'lsp-proxy' }), lsp-mode's lsp-postgres, and the Helix/Zed setups in docs/guides/ide_setup.md.
  • lsp-proxy (pgls_cli/src/commands/daemon.rs) only copies the LSP bytes between stdio and the daemon's socket. The daemon runs the language server itself (ServerFactory::new → LSPServer), with the workspace server in the same process (workspace::server_sync).
  • So $/cancelRequest reaches tower-lsp in the daemon, which drops the request future. The handler runs on a blocking thread in the daemon process, where pgls_workspace::cancellation from perf(lsp): stop cancelled requests, and run diagnostics, completions and formatting off the runtime #954 works.
  • The workspace transport (WorkspaceClient), where a cancellation would be lost, is only used by CLI commands run with --use-server. Those have nothing to cancel.
  • Nothing to change on the daemon path, so this PR doesn't touch it.

Stale analysis stops early

  • Analyser::analyse_until(params, should_stop) checks should_stop every 64 statements and returns early with AnalysisResult::stopped. analyse is analyse_until with a check that never stops, so the CLI and the tests are unchanged.
  • analyse_document passes "the document changed, or the request was cancelled", and checks the same every 64 statements while parsing the statements before the analysis.
    • Diagnostics stop when the document changes while they run. The LSP already discards diagnostics of an outdated version, so they now stop instead of finishing. pull_file_diagnostics returns nothing and skips the database checks (EXPLAIN, plpgsql_check).
    • Lint code actions also stop when the client cancels the request (they run through run_document_request since perf(lsp): run editor requests off the async runtime on a snapshot of the document #931).
  • snapshot_before, which completions and hover build from the statements before the cursor, does the same check while collecting and applying statements. It returns the database snapshot as is, which is never cached; the request ends with ContentModified or is cancelled anyway.
  • pgls_completions::complete itself works on one statement and isn't interrupted.

Tests

  • pgls_analyser: analysis_stops_when_asked. 200 statements; asked to stop at the second check, it returns the 127 statements before it and stopped.
  • pgls_workspace: test_cancelled_analysis_stops. Under a cancelled flag, diagnostics and lint code actions of a 200-statement file are empty; without it they're all there.
  • No test through the daemon socket: the language server in the daemon is the same ServerFactory/LSPServer that the LSP tests use. A test that sends $/cancelRequest needs a test client that can send a notification while it awaits a request, which ours can't.

Not covered

The --use-server CLI path still can't be cancelled (nothing sends a cancellation there).

…tions early

The analysis, the parsing of the document's statements before it, and
the snapshot that completions and hover build from the statements before
the cursor check every 64 statements whether the document changed or the
request was cancelled, and stop. Diagnostics of an outdated version are
not published anyway, and code actions and completions answer
ContentModified or are cancelled.
@psteinroe

Copy link
Copy Markdown
Collaborator Author

Superseded by #1008 (rebuild of the document caches and walk).

@psteinroe psteinroe closed this Oct 26, 2026
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