Skip to content

Temporary freeze on lsp start during roots scanning on repo with a lot of folders #312

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
6 tasks done
GuillaumeLagrange opened this issue Mar 23, 2024 · 9 comments
Closed
6 tasks done
Labels

Comments

@GuillaumeLagrange
Copy link
Contributor

GuillaumeLagrange commented Mar 23, 2024

Have you read the docs and searched existing issues?

Neovim version (nvim -v)

0.9.5-2 & Nightly

Operating system/version

Arch

Output of :checkhealth rustaceanvim

rustaceanvim: require("rustaceanvim.health").check()

Checking for Lua dependencies ~
- WARNING dap not installed. Needed for debugging features [mfussenegger/nvim-dap](https://github.com/mfussenegger/nvim-dap)

Checking external dependencies ~
- OK rust-analyzer: found rust-analyzer 1.77.0 (aedd173 2024-03-17)
- OK Cargo: found cargo 1.77.0 (3fe68eabf 2024-02-29)
- OK rustc: found rustc 1.77.0 (aedd173a2 2024-03-17)
- OK lldb: found lldb version 17.0.6

Checking config ~
- OK No errors found in config.

Checking for conflicting plugins ~
- OK No conflicting plugins detected.

Checking for tree-sitter parser ~
- OK tree-sitter parser for Rust detected.

How to reproduce the issue

With minimal config (or not), open src/main.rs in this repo.

The repo was literally created by running
cargo new big-workspace
Then cargo add crate_xxx --lib 1000 times to simulate the effect of a lot of dirs being scanned on open.
This is a simple and unrealistic repro setup, but I am experiencing similar issues on my daily work on a monorepo I cannot share here.

Expected behaviour

In VSCode, the project opens and rust-analyzer starts, and we can see the progress of the root scanning while the IDE remains responsive. It should be the same for nvim ideally.

Actual behaviour

Neovim freezes for a few seconds (between 5 and 7 on my machine) before being responsive again.

When enabling lsp debug logs (the nvim ones, readable in LspLog), I see nothing logged for the duration of the freeze, then I see the ~1000 messages like this. The hang seems to occur during the roots scanning phase of rust-analyzer.

[DEBUG][2024-03-23 00:55:05] .../vim/lsp/rpc.lua:408	"rpc.receive"	{  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/Roots Scanned",    value = {      cancellable = false,      kind = "report",      message = "1/1001: crate_367",      percentage = 0    }  }}

Each message is timestamped exactly at the same second each time

It is most likely not linked to this plugin particularly, but seems to be an issue witth nvim, rust-analyzer or both. The only discussion on the matter I found is this one: rust-lang/rust-analyzer#12613

The minimal config used to reproduce this issue.

The minimal one from the repo is enough.
@GuillaumeLagrange GuillaumeLagrange added the bug Something isn't working label Mar 23, 2024
@GuillaumeLagrange
Copy link
Contributor Author

This is an issue I have always had when running rust-analyzer through nvim-lspconfig, or rust-tools, so I do not think it is linked particularly to this plugin, but I believe solving it (even if it means a PR on nvim/ra) would improve the experience of rust on nvim overall and I believe this place is a good starting point for a discussion.

@mrcjkb mrcjkb added upstream and removed bug Something isn't working labels Mar 23, 2024
@mrcjkb
Copy link
Owner

mrcjkb commented Mar 23, 2024

Hey 👋

Thanks for the thorough research.
This indeed looks like a neovim bug. 🤔
Let's leave this issue open here though, at least until we've identified the cause.

@mrcjkb
Copy link
Owner

mrcjkb commented Mar 23, 2024

Based on the logs it looks related to Neovim's handling of LSP progress messages.
Not a solution, but we could test this theory by setting

vim.lsp.handlers['$/progress'] = nil

Looking at the code base, the default implementation fires an autocmd, which I could imagine blocking the UI if there are too many progress messages.

https://github.com/neovim/neovim/blob/881f5e59173a4f1b9a4cb16e425709e40d79d0e9/runtime/lua/vim/lsp/handlers.lua#L27

@GuillaumeLagrange
Copy link
Contributor Author

Setting the handler to nil does not change anything, the issue may be occuring during the step before.

The nvim lsp logs indicate that the last message received before the hanging is a huge client/registerCapability message, too big to paste here:
https://pastebin.com/4FcU7RtT

My bet would be parsing this message must be the reason nvim is having a stroke.

@mrcjkb
Copy link
Owner

mrcjkb commented Mar 23, 2024

Setting the handler to nil does not change anything, the issue may be occuring during the step before.

The nvim lsp logs indicate that the last message received before the hanging is a huge client/registerCapability message, too big to paste here: https://pastebin.com/4FcU7RtT

My bet would be parsing this message must be the reason nvim is having a stroke.

Hmm, we might be able to test that theory by setting server.capabilities.workspace.didChangeWatchedFiles = false.

@OneOfOne
Copy link

Setting the handler to nil does not change anything, the issue may be occuring during the step before.
The nvim lsp logs indicate that the last message received before the hanging is a huge client/registerCapability message, too big to paste here: https://pastebin.com/4FcU7RtT
My bet would be parsing this message must be the reason nvim is having a stroke.

Hmm, we might be able to test that theory by setting server.capabilities.workspace.didChangeWatchedFiles = false.

I can confirm this fixes the issue and also fixes the issue where running cargo test on a large repo would keep reloading rust_analyzer.

I'm not the OP.

My current workaround us:

{
	'mrcjkb/rustaceanvim',
	opts = function(_, opts)
		local on_attach = opts.server.on_attach
		opts.server.on_attach = function(cli, bufnr)
			on_attach(cli, bufnr)
			cli.server_capabilities.workspace.workspaceFolders = {}
		end
		return opts
	end,
},

@GuillaumeLagrange
Copy link
Contributor Author

I may be doing something wrong, but it does not fix the issue on my end.
Here is the most naive way I tried to do so:

vim.g.rustaceanvim = {
  server = {
    on_attach = function(client, _)
      client.server_capabilities.workspace.didChangeWatchedFiles = {
        dynamicRegistration = false,
        relativePatternSupport = false,
      }
    end,
  },
}

The more I investigate the more I believe it is indeed the cause though, I just noticed there is ~5 seconds between the huge log I linked and the debug log performed once it has been handled (here)

For now, a way I found to fix the freeze is by explicitly disabling the capability on client creation in rustacean, cf draft pr #352

I suspect disabling the capability in on attach comes too late ? I will use the dirty fix for a few days and report any incovenience, and if it does fix stuff I will try and open a neovim issue to get pointers to how troubleshoot this in a cleaner way.

@GuillaumeLagrange
Copy link
Contributor Author

AFAICT, it does look linked to this neovim/neovim#23291

@mrcjkb
Copy link
Owner

mrcjkb commented Apr 17, 2024

Yep. I'll close it here then, since there's nothing to be done in rustaceanvim.

@mrcjkb mrcjkb closed this as completed Apr 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants