forked from FuelLabs/sway
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Optimize LSP
parse_project
(FuelLabs#4414)
## Description Closes FuelLabs#4413 This change drastically improves the UX of the VSCode plugin in github codespaces. It's slightly noticeably faster running locally too. The key optimizations are: #### Only one thread of `parse_project` can run at a time - A write lock taken on `diagnostics` function forces the program to wait until the previous `parse_project` execution is finished - A semaphore with 2 permits accessed with `try_acquire` means that only 1 thread of `parse_project` can wait on the mutex. When the first one finishes, the waiting one will run against the latest version of the user's code. All others will not be able to acquire a permit and will exit immediately. This was a big improvement because previously, as the user was typing, 5+ threads of `parse_project` would kick off simultaneously, all operating on the same data stores (taking turns with read & write locks). We only really care that the most recent version of the user's code is compiled & indexed. #### Hot swapping the engines with write lock Previously, we only used a write lock to clear the engines, then read locks to do the rest of the parsing. After making the change to limit the # of parsing threads and the subsequent latency improvement, I encountered an issue where we'd sometimes request stale TypeIds from the engines. To prevent this, I'm using a new set of engines for compilation (`pkg::check`), and only storing them in the session once compilation is complete. The write lock only applies to the swapping process, but ensures that no readers will read incomplete data. - This also means we clear the data stores _after_ compilation is complete. - I had to replace the `read` lock from `create_runnables` since it caused a deadlock (`create_runnables` is called in the section of code that is now holding a write lock) #### Spawn blocking for parse_project We're now calling the synchronous `session::parse_project` in a [spawn_blocking](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html) thread so that it doesn't block tokio's runtime, allowing other requests like `inlay_hints` to be processed on whatever runtime threads are available. #### Publish compiler diagnostics only when they're fresh Since we have "passive" threads of `parse_project` that simply wait for the active threads to finish, there's no need for the passive threads of `parse_project` to publish their results, since they'll be the same as what the active threads before them have gathered. In practice this cuts the number of `publishDiagnostic` messages roughly in half, saving resources for the server to handle to other requests. It also reduces the amount of squiggly lines jumping around reporting warnings/errors while the user is typing. #### Performance Here's a video of it running in github codespaces on a **2-core** machine - the smallest option available. Previously it was taking upwards of 1 minute to render inlay hints, mostly due to requests timing out and getting cancelled. Now it takes 2ms plus the ~1 second of compile time :-) https://user-images.githubusercontent.com/47993817/230686772-a521c072-19c5-4729-8dad-a48630b8735d.mp4 #### Notes I had to increase the timeout on a test that waits for diagnostics to be published. I suspect this means that parsing takes slightly longer because of the locks, but overall the LSP performs better because it's doing less throwaway work. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Joshua Batty <[email protected]>
- Loading branch information
1 parent
999557c
commit cd936a5
Showing
5 changed files
with
95 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters