Skip to content

rust-analyzer with VSCode Workspaces appears to run redundant checks. #13162

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

Open
denbeigh2000 opened this issue Sep 1, 2022 · 11 comments
Open
Labels
C-support Category: support questions

Comments

@denbeigh2000
Copy link

denbeigh2000 commented Sep 1, 2022

rust-analyzer version: rust-analyzer version: 1.65.0-nightly (bc4b39c 2022-08-29)

rustc version: (eg. output of rustc -V) rustc 1.58.0-nightly (891ca5f63 2021-11-15)

relevant settings: (eg. client settings, or environment variables like CARGO, RUSTUP_HOME or CARGO_HOME)
Env (pulled from cargo check process):

CARGO_HOME=/home/USER/.cargo
RUSTUP_HOME=/home/USER/.rustup
RUSTUP_TOOLCHAIN=nightly-2021-11-16-x86_64-unknown-linux-gnu
RUST_BACKTRACE=short
RUST_RECURSION_COUNT=1

Editor configuration (VSCode workspace):

{
  "folders": [
    {
      "name": "root",
      "path": ".",
    },
    { "path": "bench" },
    { "path": "regex-capi" },
    { "path": "regex-debug" },
    { "path": "regex-syntax" },
  ],
  "settings": {
    "files.watcherExclude": {
      "**/.git/**": true,
      "**/.DS_Store": true,
      "**/target/**": true,
    },
  },
  "extensions": {
    "recommendations": [
      "rust-lang.rust-analyzer",
    ]
  },
}

Description

Hi! I am using rust-analyzer with a large, multi-language monorepo, which includes several crates spanning several editions: mostly 2018, but with a small number of 2021 crates. With this, we distribute a VSCode multi-root workspace configuration, that aims to suit most developers' needs across different languages. In this configuration, each top-level project is declared as a folder in the VSCode workspace.

When I open our workspace, rust-analyzer does some initial processing, and will then start 3 cargo check processes. These are all invoked with the --all-targets flag, and are run from the root directory of our workspace, i.e. they are all invoked with:

/home/USER/.rustup/toolchains/nightly-2021-11-16-x86_64-unknown-linux-gnu/bin/cargo check --workspace --message-format=json --manifest-path /home/USER/dev/work/REPOSITORY/Cargo.toml --all-targets

With the number of subcrates we have, this becomes a rather slow operation.

We've also observed that the number of redundant checks is proportional to the number of edition = 2021 crates we have as folders in our VSCode workspace.

  • When we have no 2021 crates declared as folders, we see only a single cargo check process, and 477 files being indexed by RA.
  • When we add a single 2021 crate as a folder, we see 2 cargo checks, and 954 (2x) files being indexed, and
  • When we add a second, 3 cargo checks and 1431 (3x) files being indexed.

Screen Shot 2022-08-30 at 7 27 06 PM

(NOTE: cargo check is absent from the above, because it finished before my screenshot captured)

Screen Shot 2022-08-30 at 7 24 27 PM


Reproduction

I can't share the full source repository, though I've found a similar repro on an OSS repository. In this case, rust-analyzer will start multiple cargo checks, also with the same redundant behaviour, but this doesn't appear to be affected by mixing and matching editions.

Expected result: A single cargo check is run for the workspace
Actual result: Multiple cargo checks are run for the workspace.
Screen Shot 2022-08-31 at 5 06 35 PM


Further analysis

I wrote a small script to collect information about my running cargo check processes to better understand what was going on. This confirmed that these processes had identical command line args, PWD and environment variables - I've included it below.

#!/usr/bin/env bash

set -uo pipefail

function collect_info() {
    PID=$1

    echo "CWD: $(ls -ld /proc/$PID/cwd)"
    echo "root: $(ls -ld /proc/$PID/root)"

    echo "cmdline: $(cat /proc/$PID/cmdline)"

    echo "Environment:"
    cat /proc/$PID/environ | tr '\0' '\n'
}

PROC_OUT="$(ps aux | grep '[c]argo check')"
if [[ $? -ne 0 ]]
then
    echo "No results found" >&2
    exit
fi

echo "$PROC_OUT" | awk '{print $2}' | while read PID
do
    FILENAME="output.$PID.txt"
    collect_info "$PID" > "$FILENAME"
    echo "Created $FILENAME" >&2
done
@denbeigh2000
Copy link
Author

Am I perhaps holding this wrong? Is there some setting that I've missed that should change this behaviour?

@bjorn3
Copy link
Member

bjorn3 commented Sep 21, 2022

Not sure why rust-analyzer would invoke multiple cargo instances (maybe it just considers every vscode workspace member individually), but if they all operate on the same cargo workspace, it shouldn't slow anything down as all invocations except for the first will simply block until the first is done and then see that nothing needs to be done anymore and just exit.

@denbeigh2000
Copy link
Author

denbeigh2000 commented Sep 21, 2022

This makes sense, but in practice in our monorepo, removing my 2021 workspace roots gives me a substantial drop in ongoing memory usage, and rust-analyzer is ready (providing intellisense/autocompletion) ~1m faster. Could there be some other action going on to cause RA to not think these as part of the "same workspace"?

If there's anything useful I can share that would help troubleshoot what's going on there, I'd be very happy to provide it.

@bjorn3
Copy link
Member

bjorn3 commented Sep 21, 2022

Unfortunately I'm not really familiar with the relevant code.

@denbeigh2000
Copy link
Author

No worries, I appreciate your input at any rate.

I think we'll move forward by removing rust projects as roots from our VSCode workspace until this is addressed in some way.

@Veykril
Copy link
Member

Veykril commented Sep 21, 2022

r-a invokes a check per cargo workspace in the opened VSCode workspace. It is rather odd if it invokes all of those with the same manifest path though, this sounds like you have a somewhat "special" set up maybe that confuses r-a, though I can't really say much about that without knowing the project structure of course. I'll take a look at the regex example when I get the time, although I doubt that will run the checks with the same manifest path for the workspaces.

@denbeigh2000
Copy link
Author

denbeigh2000 commented Sep 21, 2022

I was a little surprised too, but I was definitely able to reliably reproduce this with the given config for regex.

It's possible that this is specific to the VSCode integration, somehow (as I tested + reproduced this only in VSCode).

@Veykril
Copy link
Member

Veykril commented Jan 23, 2023

Okay finally took a look at this, and it makes sense why this is happening. You are telling VSCode, and rust-analyzer therefor that there are 5 projects via the folders setting, all of these are cargo workspaces that belong to the main regex workspace, so rust-analyzer falls back to that since that is the top level workspace that is still part of the vscode workspace. In short, you specifying all the subcargo workspaces as folders via path, makes r-a load the main cargo workspace 5 times. There is not much we can do here I believe because we rely on cargo workspaces.

@Veykril Veykril added the C-support Category: support questions label Feb 6, 2023
@bmisiak
Copy link

bmisiak commented Nov 22, 2023

@Veykril Hmmm any hint as to the difference in behavior between 2018 crates and 2021 crates? Are you saying we have to bring it up to the cargo team?

@bmisiak
Copy link

bmisiak commented Nov 22, 2023

#14571 related

@Veykril
Copy link
Member

Veykril commented Nov 22, 2023

The editions shouldn't matter here (and if they did it would still be a r-a issue, not cargo), and in fact the linked issue is basically the same as I described in my comment earlier so this can technically be closed. The regex case described in this issue should work properly now (that is only spawn on cargo check).

Would need to double check that it is fixed in the regex case though before closing this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-support Category: support questions
Projects
None yet
Development

No branches or pull requests

4 participants