Skip to content

Fix no inlay hints / unresolved tokens until manual edit to refresh #5693

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 2 commits into from
Aug 9, 2020

Conversation

Veetaha
Copy link
Contributor

@Veetaha Veetaha commented Aug 8, 2020

Fixes #5349

Now we return ContentModified during the workspace loading. This signifies the language
client to retry the operation (i.e. the client will
continue polling the server while it returns ContentModified).
I believe that there might be cases of overly big projects where the backoff
logic we have setup in sendRequestWithRetry (which we use for inlay hints)
might bail too early (currently the largest retry standby time is 10 seconds).
However, I've tried on one of my project with 500+ dependencies and it is still enough.

Here are the examples before/after the change (the gifs are quite lengthy because they show testing rather large cargo workspace).

Before

Here you can see that the client receives empty array of inlay hints and does nothing more.
Same applies to semantic tokens. The client receives unresolved tokens and does nothing more.
The user needs to do a manual edit to refresh the editor.

prev-demo

After

Here the server returns ContentModified, so the client periodically retries the requests and eventually receives the wellformed response.

new-demo

No we return ContentModified during the workspace loading. This signifies the language
client to retry the operation (i.e. the client will
continue polling the server while it returns ContentModified).
I believe that there might be cases of overly big projects where the backoff
logic we have setup in `sendRequestWithRetry` (which we use for inlay hints)
might bail too early (currently the largest retry standby time is 10 seconds).
However, I've tried on one of my project with 500+ dependencies and it is still enough.
@kjeremy
Copy link
Contributor

kjeremy commented Aug 8, 2020

I think this approach makes sense! Do we need to let exit/shutdown go through? I haven't looked too closely at it.

@jonas-schievink
Copy link
Contributor

I believe that there might be cases of overly big projects where the backoff
logic we have setup in sendRequestWithRetry (which we use for inlay hints)
might bail too early (currently the largest retry standby time is 10 seconds).

My understanding is that the Loading status only persists until the VFS has loaded all files into memory, which hopefully won't take that long.

I wouldn't be surprised if some clients will have problems with initialize returning ContentModified though, so I think I agree with @kjeremy that we shouldn't return it for initialize and shutdown.

@kjeremy
Copy link
Contributor

kjeremy commented Aug 9, 2020

During initialize the server should respond to a request with -32002 which is serverNotInitialized. At the point in this PR though we've already made it past the initialize phase (we enter main_loop after initialization has completed) so I don't think that applies here.

The shutdown request from the client should probably not respond with ContentModified though. See: https://microsoft.github.io/language-server-protocol/specifications/specification-3-16/#shutdown

@jonas-schievink
Copy link
Contributor

Ah, I see

@Veetaha
Copy link
Contributor Author

Veetaha commented Aug 9, 2020

Yup, I tried returning ServerNotInitialized at the same place I've put ContentModified and the language client just considered this an unrecoverable error.
It's just that we have such a code flow where part of initialization is in the main loop. I think the reason for this is allowing for some interactions during the initial loading, but this leads to inconsistencies. Maybe some requests do may work while loading is in process?

@kjeremy
Copy link
Contributor

kjeremy commented Aug 9, 2020

Yup, I tried returning ServerNotInitialized at the same place I've put ContentModified and the language client just considered this an unrecoverable error.

That makes sense since we've already processed the initialize request and given the response back to the client.

It's just that we have such a code flow where part of initialization is in the main loop. I think the reason for this is allowing for some interactions during the initial loading, but this leads to inconsistencies. Maybe some requests do may work while loading is in process?

At this point in the code the LSP client considers us initialized. The spec makes no mention of the expected behavior (as in "what does initialization really mean?"). I think your solution to return ContentModified here for every request (except shutdown!) is entirely reasonable especially in light of our reloading capability.

@Veetaha
Copy link
Contributor Author

Veetaha commented Aug 9, 2020

I've added a condition to let shutdown request pass through, though we do nothing in response to it right now.
It will be reasonable to add a shutdown state to gate further requests as kjeremy mentioned here #5696, but let's leave it for other RP?

@Veetaha Veetaha force-pushed the feat/server-not-initialized branch from 6144784 to f4833cb Compare August 9, 2020 21:46
@Veetaha
Copy link
Contributor Author

Veetaha commented Aug 9, 2020

Hmm, is this a bug with cargo fmt, but for some reason it adds two closing curly braces at the end of on_request function and shifts the comment....
UPD, oh yeah, not quals in rust is not !== but !=

@kjeremy
Copy link
Contributor

kjeremy commented Aug 9, 2020

Does cargo xtask format make a difference?

@Veetaha Veetaha force-pushed the feat/server-not-initialized branch from f4833cb to dbe7ede Compare August 9, 2020 21:50
@Veetaha
Copy link
Contributor Author

Veetaha commented Aug 9, 2020

Nvm, that's tripple equals what makes cargo fmt wild...

@kjeremy
Copy link
Contributor

kjeremy commented Aug 9, 2020

UPD, oh yeah, not quals in rust is not !== but !=

Relevant :) rust-lang/rust#75321

@Veetaha
Copy link
Contributor Author

Veetaha commented Aug 9, 2020

Lol, what a coincidence :D

@kjeremy
Copy link
Contributor

kjeremy commented Aug 9, 2020

It will be reasonable to add a shutdown state to gate further requests as kjeremy mentioned here #5696, but let's leave it for other RP?

Yeah I think that should be a separate PR.

@jonas-schievink
Copy link
Contributor

bors r+

@bors
Copy link
Contributor

bors bot commented Aug 9, 2020

@bors bors bot merged commit b1cb4ac into rust-lang:master Aug 9, 2020
bors bot added a commit that referenced this pull request Aug 10, 2020
5696: Return InvalidRequest if Shutdown has been requested r=kjeremy a=kjeremy

From the LSP 3.16 spec: "If a server receives requests after a shutdown request those requests should error with InvalidRequest."

Realized this behavior was missing while looking at #5693. Question on notification behavior is tracked at microsoft/language-server-protocol#1066

Co-authored-by: Jeremy Kolb <kjeremy@gmail.com>
@Veetaha Veetaha deleted the feat/server-not-initialized branch August 10, 2020 23:20
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

inlay hints cannot be shown just after openning project, edit is necessary to trigger the generation
3 participants