sway icon indicating copy to clipboard operation
sway copied to clipboard

Use a single Engines & TokenMap in the language server to share cache across large workspaces

Open JoshuaBatty opened this issue 1 year ago • 2 comments

I'm currently helping Fluid Protocol debug bad LSP performance on their workspace. The workspace had 20+ sway projects and 1 large "libraries" project that contain 20+ sway libraries.

When clicking through the various projects, I've noticed that the amount of RAM used can easily reach 20+ gig. It seems we are recompiling std / core and shared libraries for each project. So if we click through all 20 projects, we have compiled the std lib 20 times and store it in the servers memory. For example, if we put a print in the following query engine code

pub fn insert_programs_cache_entry(&self, entry: ProgramsCacheEntry) {
    eprintln!("👷 Instering programs cache entry: {:?}", entry.path);
    let mut cache = self.programs_cache.write().unwrap();
    cache.insert(entry.path.clone(), entry);
}

We get the below.

Screenshot 2024-04-15 at 1 30 43 pm

Instead, we should be having a single QueryEngine stored in ServerState that is used across each project. This way we will be able to drastically reduce the memory footprint for projects like this, and greatly speed up the time it takes for the server to initialise when a new project is navigated to.

JoshuaBatty avatar Apr 15 '24 03:04 JoshuaBatty

related to #5645

JoshuaBatty avatar Apr 15 '24 03:04 JoshuaBatty

Ok it's not as simple as just having the QueryEngine shared across workspace members. This will allow us to share the cached AST but the type and decl engines still need to be populated. What we probably want is to have the Engines and other items like the TokenMap stored in the ServerState rather than within each Session.

This is going to involve quite a bit of code re-arranging but should be feasible.

JoshuaBatty avatar Apr 16 '24 05:04 JoshuaBatty