-
Notifications
You must be signed in to change notification settings - Fork 18k
x/tools/gopls: client receives old diagnostics #36601
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
Comments
@stamblerre I'll leave you to decide whether this is |
This does seem like a bug, particularly because it's this v3 that keeps coming back. I'm not sure if it's a v0.3.0 blocker, but it's definitely something to look into soon. |
Following a conversation with @leitzler yesterday, I think we need to consider this a I will try to explain why by making clear my understanding on a few points. Because if any of this is wrong my argument might well fall to pieces!
On Slack last night, I think @heschik reached the same conclusion as point 9:
Given point 8 above (and the conclusion in point 9) I therefore think it is wrong/impossible for the client to try and drop non-new diagnostics. Hence, per @leitzler's observation, we should not be merging govim/govim#663. It was suggested in #36452 (comment) that the client should only apply diagnostics for a file if that version matches the current (from the client's perspective) file version. Given points 4, 5 and 7 above, I think we have to conclude this is not possible. Rather that the client has to apply diagnostics on a "best efforts" basis, in the knowledge that, under normal operation, the "right" diagnostics will eventually arrive and "put things right". My conclusions from the above are therefore:
Any corrections/comments etc on the above gratefully received 😄 |
Change https://golang.org/cl/215298 mentions this issue: |
This change uses snapshot IDs instead of file versions to determine if diagnostics are stale. Fixes golang/go#36601. Change-Id: I7727a30222fecf2d7733fa013c6cee6338ffd968
Rather bizarrely, we're still seeing this with golang/tools@633b092.
|
Some quick observations: |
I too see something like this, but without any saving (maybe not the same, then?). A very quick example where I see a change to v3, and then gopls responds with an empty v1. I don't see any diagnostics for v2, presumably because they're the same as the "real" v1. https://gist.github.com/zikaeroh/4146e6e154d622317322bab903c24fd8 |
I'm able to reliably reproduce this locally and on Travis for various tests. I haven't spotted a pattern yet as to why/when this happens. Reproducing locally via:
Then finding affected tests via:
In each script directory beneath My machine is not super powerful which might be significant. Whether you run with race or not also appears to not be significant. But adding Removing the saves (as suggested by @stamblerre) also didn't appear to "fix" things. Instead we get a slightly different pattern of diagnostics for this test:
Indeed I'm not really sure there's much of a pattern. Given the logic here: we know the snapshot ID of the diagnostics we receive must be greater than or equal to that we received previously. Indeed through some simple logging I can confirm in this case the snapshot ID is indeed greater. So it appears the question we need to answer is: how can a later snapshot get an earlier version of a file? |
Some progress. Last night Rebecca asked (via Slack):
As in, "during the test, do any of the files end up with the same contents as previous versions?" I answered "no" - but that answer was wrong. Really sorry about that @stamblerre. In fact, The good news is that, despite the wrong version numbers in the diagnostics, the result is correct. i.e. the diagnostics are what we are expecting. But the wrong version numbers seem to suggest to me that we are caching stuff for too long. The fact that we are able to find a cache hit for something that happened four versions ago seems strange - because surely we should only be caching the last diagnostics for any given file? But I'm only guessing as to what might be happening here. Whatever the cause, we should fix the fact that old version numbers are sent as part of the diagnostics. Therefore, subject to any further issues that @zikaeroh might report, this is probably not a v0.3.0 blocker. What do you think @stamblerre? |
So basically back to #36476? |
Possibly, but now at least the diagnostics are correct, only the version is wrong. |
👍 I think that I never saw any incorrect diagnostics back then either, but might have missed that. |
Sorry, accidentally sent that last message too early. Before our conclusions in #36601 (comment), we were making things worse by ignoring diagnostics for old file versions. It's quite possible, as you say, that the diagnostics were actually correct in those cases (but wouldn't have been guaranteed to be correct in all cases) and we were making them wrong by ignoring the diagnostics marked with old versions. But given that a) we now filter diagnostics as a function of snapshot ID and b) we have removed the client filter (ignoring for one second that it wouldn't have worked properly in any case), we are at least able to see and hypothesise that only the file version number is wrong. |
In my case, I don't see that the diagnostics are correct. Here is a screencast and corresponding logs: Starting with: package main
func main() {
x := 123
} I see an error on This is seen in the logs, where they start with {
"textDocument": {
"uri": "file:///home/jake/testproj/gopls/lastline/main.go",
"languageId": "go",
"version": 1,
"text": "package main\n\nfunc main() {\n\tx := 123\n}\n"
}
} Followed by {
"uri": "file:///home/jake/testproj/gopls/lastline/main.go",
"version": 1,
"diagnostics": [
{
"range": { "start": { "line": 3, "character": 1 }, "end": { "line": 3, "character": 2 } },
"severity": 1,
"source": "compiler",
"message": "x declared but not used"
}
]
} Now, me hitting enter does: {
"textDocument": {
"uri": "file:///home/jake/testproj/gopls/lastline/main.go",
"version": 2
},
"contentChanges": [
{
"range": { "start": { "line": 3, "character": 9 }, "end": { "line": 3, "character": 9 } },
"rangeLength": 0,
"text": "\n\t"
}
]
} With no diagnostics sent, as they appear to be identical. Then, the undo results in the {
"textDocument": {
"uri": "file:///home/jake/testproj/gopls/lastline/main.go",
"version": 3
},
"contentChanges": [
{
"range": { "start": { "line": 3, "character": 9 }, "end": { "line": 4, "character": 1 } },
"rangeLength": 2,
"text": ""
}
]
} And the
gopls is sending back "version 1 has no diagnostics", and not "version 3 has these diagnostics" (or sending nothing, since the diagnostics shouldn't have changed in any of these versions), the effect of which (in my editor) appears to be to just display nothing. Maybe this is some other bug, as it's both old and wrong diagnostics. I plan to bisect this. |
Bisect says: https://go-review.googlesource.com/c/tools/+/214586 A log of the same done at the commit before that CL: https://gist.github.com/zikaeroh/deefe190ba7df51ef63e2646b5d3daad In this log, there's only a single |
I can confirm we're also see #36601 (comment) in |
FWIW we're having success using a partial revert of CL 214586. I've pushed up https://go-review.googlesource.com/c/tools/+/215239 to show that partial revert. But I totally defer to @stamblerre on the proper fix. We're only doing this temporarily to fix |
Change https://golang.org/cl/215680 mentions this issue: |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
This may or may not be a problem; raising for completeness given previous CLs have sought to prevent old diagnostics being sent to the client.
Per conversations with @stamblerre we have a defence against this in place in
govim
so we are not seeing any problems in our tests. i.e. if these old diagnostics are ignored, the non-old diagnostics are as expected.In a few tests we randomly see
gopls
sendinggovim
old diagnostics. That is for a given file, we receive diagnostics for a version less than the latest version we received fromgopls
.This doesn't appear to be specific to a given test/scenario.
Attached is a
gopls
log file from a test that looks to verify case insensitive completion:gopls.log
The sequence of diagnostic notifications here is:
What did you expect to see?
Monotonically increasing version numbers for a file's diagnostics.
What did you see instead?
As above.
cc @stamblerre
FYI @leitzler
The text was updated successfully, but these errors were encountered: