-
Notifications
You must be signed in to change notification settings - Fork 196
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
Bypass file_server for some file existence checks #390
Conversation
Nice find @mattbaker. The same fix is also needed in elixir_sense.
I explained my original reasoning behind a custom |
Ah, that's interesting @lukaszsamson, thanks! And thanks for the information on |
Thanks for this @mattbaker ❤️! This looks like it should help with the speed significantly. |
Hey folks, I'm checking this out locally to test. Two questions I'm hoping I can get answer to: Does format on save wait for all compilation to complete before formatting? Does it reformat all files in the code base or just the one that was changed? |
@benwilson512 - this is my understanding:
|
Played around with #391 as a solution to the second bullet, but I'm not sure how I feel about it. |
This addresses what I believe is the root cause of #381.
During indexing the
WorkspaceSymbols
genserver works its way through the result of:code.all_loaded/0
, callingFile.exists?
in the course of its work for each entry in the list of loaded modules. This occurs concurrently acrossn
processes wheren
is the scheduler count. On my current project of decent size:code.all_loaded/0
returns 550 entries.The
File.exists?
checks are filling the message queue of Erlang'sfile_server
process, and I think this is causing other file operations to block until it can work through the queue. If you launch the Observer you can see this happen on the process tab, and it would explain why seemingly independent parts of the Elixir LS application are blocking each other.I think the regression itself would have been introduced in #110 with the introduction of workspace symbols support. I'm unclear on why it got worse for people in the latest Elixir LS release, but as I mentioned in #381 I wonder if the Elixir and OTP upgrade is a piece of the puzzle? Maybe someone has a better idea.
This PR passes the
:raw
option toFile.exists?
, which causes the file existence check to bypass the Erlang file server, which I believe is safe under these circumstances.This seemed to resolve the specific issue I outlined in #381. On my machine it also reduced the cumulative workspace symbol indexing time by 50% for the initial indexing phase and 70% for subsequent updates. I suspect this is because the individual tasks spawned by WorkspaceSymbols aren't blocking each other's
File.exists?
checks.As an aside on the subject of performance — after this change I tried
Task.async_stream
as well as the customprocess_chunked
family of functions and found no difference between them. It may be worth revisiting if we can simply useTask.async_stream
since it will be familiar to more people. It is, of course, also possible I measured incorrectly!Perhaps @benwilson512 or @BlueHotDog could give this change a try to see if it helps?