Skip to content
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

Send exit notification to not-yet-initialized language servers instead of shutdown #5732

Closed
Seelengrab opened this issue Jan 30, 2023 · 5 comments
Labels
A-language-server Area: Language server client C-bug Category: This is a bug upstream

Comments

@Seelengrab
Copy link
Contributor

Seelengrab commented Jan 30, 2023

Summary

Per the spec for the initialization of an LS:

Notifications should be dropped, except for the exit notification. This will allow the exit of a server without an initialize request.

So during initialization, a conforming LS should still respect the exit notification and exit (almost) immediately. Right now we send (as far as I can tell) shutdown here:

helix/helix-view/src/editor.rs

Lines 1456 to 1466 in 4d548a0

pub async fn close_language_servers(
&self,
timeout: Option<u64>,
) -> Result<(), tokio::time::error::Elapsed> {
tokio::time::timeout(
Duration::from_millis(timeout.unwrap_or(3000)),
future::join_all(
self.language_servers
.iter_clients()
.map(|client| client.force_shutdown()),
),

pub async fn force_shutdown(&self) -> Result<()> {
if let Err(e) = self.shutdown().await {
log::warn!("language server failed to terminate gracefully - {}", e);
}
self.exit().await
}

which should check whether the language server is initialized and send exit directly instead, if it isn't.

Reproduction Steps

I tried this:

  1. hx -vvvvv some_julia_file.jl
  2. :q as soon as the editor is up.

It should be reproducible with any LS that takes a long time to initialize, the julia one without a sysimage is just "perfect" for this. Takes about 6 seconds to initialize.

Helix log

~/.cache/helix/helix.log
2023-01-30T12:32:36.584 helix_loader [DEBUG] Located configuration folders: []
2023-01-30T12:32:36.588 helix_view::clipboard [INFO] Using wl-copy+wl-paste to interact with the system and selection (primary) clipboard
2023-01-30T12:32:36.624 mio::poll [TRACE] registering event source with poller: token=Token(0), interests=READABLE | WRITABLE
2023-01-30T12:32:36.624 mio::poll [TRACE] registering event source with poller: token=Token(1), interests=READABLE | WRITABLE
2023-01-30T12:32:36.624 mio::poll [TRACE] registering event source with poller: token=Token(2), interests=READABLE | WRITABLE
2023-01-30T12:32:36.624 helix_view::editor [DEBUG] editor status: Loaded 1 files.
2023-01-30T12:32:36.624 helix_lsp::transport [INFO] -> {"jsonrpc":"2.0","method":"initialize","params":... 
 cut short for conciseness
2023-01-30T12:32:36.624 mio::poll [TRACE] registering event source with poller: token=Token(3), interests=READABLE | WRITABLE
2023-01-30T12:32:36.624 mio::poll [TRACE] registering event source with poller: token=Token(4), interests=READABLE | WRITABLE
2023-01-30T12:32:36.624 mio::poll [TRACE] registering event source with poller: token=Token(0), interests=READABLE
2023-01-30T12:32:36.624 mio::poll [TRACE] registering event source with poller: token=Token(1), interests=READABLE
2023-01-30T12:32:36.624 helix_view::document [DEBUG] id 1 modified - last saved: 0, current: 0
2023-01-30T12:32:36.989 helix_term::application [DEBUG] received editor event: IdleTimer
2023-01-30T12:32:37.634 helix_view::document [DEBUG] id 1 modified - last saved: 0, current: 0
2023-01-30T12:32:37.714 helix_term::commands::typed [DEBUG] quitting...
2023-01-30T12:32:37.714 helix_view::document [DEBUG] id 1 modified - last saved: 0, current: 0
2023-01-30T12:32:37.906 helix_term::commands::typed [DEBUG] quitting...
2023-01-30T12:32:37.906 helix_view::document [DEBUG] id 1 modified - last saved: 0, current: 0
2023-01-30T12:32:37.906 helix_term::job [DEBUG] waiting on jobs...
2023-01-30T12:32:37.906 helix_term::job [DEBUG] waiting on jobs...
2023-01-30T12:32:37.906 helix_lsp::transport [INFO] Language server not initialized, delaying request
2023-01-30T12:32:40.907 helix_term::application [ERROR] Timed out waiting for language servers to shutdown
2023-01-30T12:32:40.908 mio::poll [TRACE] deregistering event source from poller
2023-01-30T12:32:40.908 mio::poll [TRACE] deregistering event source from poller
2023-01-30T12:32:40.908 mio::poll [TRACE] deregistering event source from poller
2023-01-30T12:32:40.908 mio::poll [TRACE] deregistering event source from poller
2023-01-30T12:32:40.908 mio::poll [TRACE] deregistering event source from poller

Platform

Linux tower 6.1.8-arch1-1 #1 SMP PREEMPT_DYNAMIC Tue, 24 Jan 2023 21:07:04 +0000 x86_64 GNU/Linux

Terminal Emulator

foot version: 1.13.1 +pgo +ime +graphemes -assertions

Helix Version

helix 22.12

@Seelengrab Seelengrab added the C-bug Category: This is a bug label Jan 30, 2023
@pascalkuthe pascalkuthe added the A-language-server Area: Language server client label Jan 30, 2023
@kirawi kirawi added E-easy Call for participation: Experience needed to fix: Easy / not much E-good-first-issue Call for participation: Issues suitable for new contributors labels Feb 5, 2023
@pascalkuthe pascalkuthe removed the E-good-first-issue Call for participation: Issues suitable for new contributors label Feb 6, 2023
@pascalkuthe
Copy link
Member

You stopped reading at the first relevant item but the more important part is the second paragraph:

Until the server has responded to the initialize request with an InitializeResult, the client must not send any additional requests or notifications to the server.

Helix follows the spec and sending any notication earlier is pointless as helix just drops any notification that occur before the server has initialized. There is really nothing we can do about this as there is fundementally no way to cancel the initialization currently.

This is actually a current shortcoming of the LSP spec microsoft/language-server-protocol#246. Helix does about aswell we could here. Timing out is exactly the right behavior here

@pascalkuthe pascalkuthe added upstream and removed E-easy Call for participation: Experience needed to fix: Easy / not much labels Feb 6, 2023
@pascalkuthe
Copy link
Member

Maybe that is something that could be improved in julia-ls tough as I am not encoutering hte same problem with other LSPs like RA

@Seelengrab
Copy link
Contributor Author

Seelengrab commented Feb 7, 2023

You stopped reading at the first relevant item but the more important part is the second paragraph:

I did not "stop reading", but I took that first mention of allowing exit to mean "also during initialization". Seeing as there's even an issue about this on the LSP repo, I take it my "confusion" was warranted.

I do agree though that this would not be an issue if the julia-ls were to have a shorter initialization phase..

@the-mikedavis
Copy link
Member

Closed by #7449. Now we don't send / await the shutdown response from the server when shutting down, we just exit. We could add an extra check to send 'exit' if we haven't sent the initialize request yet but we send that basically immediately so it's probably not worth it.

@Seelengrab
Copy link
Contributor Author

Weee, fast open & close of julia files, here we come :) Thanks so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-language-server Area: Language server client C-bug Category: This is a bug upstream
Projects
None yet
Development

No branches or pull requests

4 participants