Skip to content

vscode workspaces don't play nicely with r-a #14571

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
Veykril opened this issue Apr 14, 2023 · 7 comments · Fixed by #14603 or #14651
Closed

vscode workspaces don't play nicely with r-a #14571

Veykril opened this issue Apr 14, 2023 · 7 comments · Fixed by #14603 or #14651
Labels
A-perf performance issues A-vscode vscode plugin issues C-bug Category: bug E-unknown It's unclear if the issue is E-hard or E-easy without digging in

Comments

@Veykril
Copy link
Member

Veykril commented Apr 14, 2023

When using a code workspace where a cargo workspace is split up into multiple folder views, r-a will duplicate the loaded cargo workspace for each folder currently which leads to excessive memory usage. We should investigate if we can prevent this from happening somehow

@Veykril Veykril added A-vscode vscode plugin issues A-perf performance issues C-bug Category: bug labels Apr 14, 2023
@Veykril Veykril added the E-unknown It's unclear if the issue is E-hard or E-easy without digging in label Apr 14, 2023
@Veykril
Copy link
Member Author

Veykril commented Apr 14, 2023

So basically I think the server should try to dedup/map workspace folders that indirectly point to the same top-level cargo workspace. We discover them here https://github.com/veykril/rust-analyzer/blob/3c7b6716d1ab458664a8b372b79347b9a9cacb98/crates/rust-analyzer/src/config.rs#L753 where workspace roots are the folders supplied by VSCode.

@zaurask
Copy link

zaurask commented Apr 18, 2023

Short answer (realized while writing long answer): Looking into your fix #14603 I recognized that

let mut i = 0;
while i < workspaces.len() {
if let Ok(w) = &workspaces[i] {
if let Some(dupe) = workspaces[i + 1..]
.iter()
.filter_map(|it| it.as_ref().ok())
.position(|ws| ws.eq_ignore_build_data(w))
{
_ = workspaces.remove(dupe);
}
}
i += 1;
}
is not working as intended through two problems:

  1. Position returns the index inside the slice which you are then using to remove from the whole vec which results in removing the wrong element.
  2. To remove duplicates every element has to be compared to all others. Currently through advancing i and slicing, all elements with index < i are not taken into account for subsequent comparisons.

Possible fix:

while i < workspaces.len() {
    if let Ok(w) = &workspaces[i] {
        match workspaces
            .iter()
            .filter_map(|it| it.as_ref().ok())
            .enumerate().filter(|&(idx, _)| idx != i).map(|(_, v)| v)
            .position(|ws| ws.eq_ignore_build_data(w))
        {
            Some(dupe) => _ = workspaces.remove(dupe),
            None => i += 1,
        }
    } else {
        i += 1;
    }
}
Long answer: Coincidentally I have also been looking at this issue (for learning purposes) and I suspect your fix #14603 does not correct the excess memory usage through duplicated cargo workspaces.

My test setup is a vscode workspace with folders for each crate from rust-analyzer basically duplicating the cargo workspace. With your fix memory usage still grows to 6.9 GB in the vscode workspace compared to ~870 MB when opening the cargo workspace under vscode.

Debugging the vscode workspace indicates that

let mut i = 0;
while i < workspaces.len() {
if let Ok(w) = &workspaces[i] {
if let Some(dupe) = workspaces[i + 1..]
.iter()
.filter_map(|it| it.as_ref().ok())
.position(|ws| ws.eq_ignore_build_data(w))
{
_ = workspaces.remove(dupe);
}
}
i += 1;
}
does not remove duplicate cargo workspaces properly since the crates from rust-analyzer clearly belong to only one cargo workspace.

@Veykril
Copy link
Member Author

Veykril commented Apr 19, 2023

1.) You are right, if we dedup we are moving two indices instead of one (classic modifying collection while iterating it mistake)
2.) This should be fine, we are skipping comparisons of elements that we already compared for the given index, that is we compare the first element with everything else, the second with everything but the first (which is fine, since we compared it with the first when comparing for the first element), etc

@Veykril
Copy link
Member Author

Veykril commented Apr 19, 2023

Debugging the vscode workspace indicates that ... does not remove duplicate cargo workspaces properly since the crates from rust-analyzer clearly belong to only one cargo workspace.

Can you explain this more? It did remove duplicates in my testing, I used a vscode workspace that had 2 folders opened pointing to 2 crates of a cargo workspace resulting in rust-analyzer deduplicating the loaded projects to the cargo workspace once instead of twice.

@Veykril Veykril reopened this Apr 19, 2023
@zaurask
Copy link

zaurask commented Apr 19, 2023

1.) You are right, if we dedup we are moving two indices instead of one (classic modifying collection while iterating it mistake) 2.) This should be fine, we are skipping comparisons of elements that we already compared for the given index, that is we compare the first element with everything else, the second with everything but the first (which is fine, since we compared it with the first when comparing for the first element), etc

In 2) position() short-circuits, so if one match is found all other elements are not compared to and the index is advanced. Details about my debugging I can explain, when I am at my computer.

@Veykril
Copy link
Member Author

Veykril commented Apr 19, 2023

In 2) position() short-circuits, so if one match is found all other elements are not compared to and the index is advanced

Ah, no need to give me details now I understand what you were trying to get at. Yes you are correct this is also a bug.

@kyle-leonhard
Copy link

@bors , sorry for reviving this old issue, but I ran into this after switching to cargo workspaces. I'm seeing the same problem duplicated once for each crate in the workspace. I also use VSCode code workspaces, 1 for each crate.

Was there a fix for this available?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-perf performance issues A-vscode vscode plugin issues C-bug Category: bug E-unknown It's unclear if the issue is E-hard or E-easy without digging in
Projects
None yet
3 participants