-
Notifications
You must be signed in to change notification settings - Fork 17
Add extra lsp features #204
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
Conversation
So, I believe that I've found three issues, some of which I'm not sure what the best way of fixing is, for now I've just implemented "hacky" workarounds to demonstrate that these should fix the issue. Current ArchitectureJust to briefly summarize my understanding of the current architecture: At the start of the communication chain, we have two "message reporting tasks", namely verification tasks and AST construction tasks. Those tasks regularly send messages to the "reporter (such as when exception occurs, when a new state is reached, etc.), which in this case is a Queue Actor. Once they send a message. The queue actor receives those messages and puts them into a queue. Others can "subscribe" to those queues and receive message there. In our case, this is what the "RelayActor" does, who received those messages and will use them to update the state in the LSP server. Problem 1: Dead lettersThe first problem I noticed is that I always kept getting those "dead letter" messages, even for very simple verification tasks. If I understood correctly, the reason for this is that at some point, we destroy the relay actor responsible for receiving the messages from AST constructions: viperserver/src/main/scala/viper/server/vsi/VerificationServer.scala Lines 168 to 173 in f5e2501
We only do this until the queue is completed (i.e. AST construction finished), but apparently akka still sends a final "Success" message after the Problem 2: IDELanguageClientCurrently, in the client coordinator, we store the IdeLanguageClient as an option which is set once on initialization, and set to null on exiting: viperserver/src/main/scala/viper/server/frontends/lsp/ClientCoordinator.scala Lines 22 to 44 in f5e2501
This is a bit of a problem because during tests because it can happen that we disconnect while a verification or something else is still running, and thus each call to Problem 3: Terminating a null job actorThe third problem that caused the stress test "quickly switching backends" to get stuck when a file was verified that doesn't reach the verification stage (e.g. due to a parsing error) is due to this part: viperserver/src/main/scala/viper/server/frontends/lsp/ViperServerService.scala Lines 117 to 125 in f5e2501
The problem is that we set the job actor of this verification to null when AST creation didn't complete:
And thus, we try to terminate a job actor that is null, which results in the server completely hanging. I fixed this by adding a simple null check before doing so, I believe this can be taken as is. I've pushed my changes here, though as I said this still needs cleaning up and the first problem requires a more principled solution: LaurenzV@99b5bd4 If I run the Viper IDE tests using those changes, all tests seem to pass for me locally. :) |
@LaurenzV Problem 3 seems to be the main thing we were looking for, great that you figured that out and that the solution is quite simple! I am not entirely sure if problem 2 is new / related to the current issues. I do not love the solution of using a MockClient outside of tests. Can this only occur during tests? |
It's probably unrelated to the specific test failure, yes, but it's not unrelated to the PR since afaik it was introduced here in the first place. But it probably should still be fixed before this PR is merged, it's an issue after all, and I'm not sure whether it could lead to other weirdness.
Same as above, it might not be related to that issue specifically, but I still think it should be addressed before merging. WIth that said, if you want I can try whether just applying solution 3 fixes all of the test failures. |
Ah I was assuming (for no reason) that at least Problem 1 was previously existing. Yeah if these are regressions then we should definitely address them! |
OK I have talked with @ArquintL and decided that we prefer following solution to problem 2: instead of setting |
@rayman2000 I took a look, and indeed it seems like on the current main branch, relay actors are never killed. I verified this by adding
to the respective classes, for queue actors the message is printed after each parse/verification step, while for the relay actor such a message is never printed. So I guess if we decide to just not kill the actor, it at least wouldn't be a regression, but obiously it would still be better to fix the underlying problem. |
@JonasAlaif and I have decided to just not kill the actors. The effort to fix this seems pretty large (mostly because no one really understands the actor model we use...) and it is not a regression, the issue existed beforehand as well. While having unnecessary actors lying around is not ideal, for known usages of ViperServer this has not been an issue so far. |
Linard and I have done some more digging and found some more issues. First of all, I get stracktraces when I verify multiple files after each other, one of the gets called here is called on None:
Second of all, we printed out all of the existing actors over time. It looks like each edit of a file causes a new AST Actor to be created and they are never removed, even with the Poison Pills added back in. So the list of actors grows fairly quickly if you just edit a file a couple of times. This feels bad enough that probably do not want to just merge it as is. |
So should I prioritize looking into this over trying to rebase my existing branches on this one? |
All right, gang, it's update time!
@JonasAlaif the issue here is still open:
This is all your changes and is not akka related, so I would be grateful if you could take a look. One of the gets is called on None if I quickly click between multiple files in the IDE. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only made a quick pass over the changes and left some comments
src/main/scala/viper/server/frontends/lsp/ClientCoordinator.scala
Outdated
Show resolved
Hide resolved
src/main/scala/viper/server/frontends/lsp/ClientCoordinator.scala
Outdated
Show resolved
Hide resolved
src/main/scala/viper/server/frontends/lsp/ast/utility/GotoDefinition.scala
Outdated
Show resolved
Hide resolved
src/main/scala/viper/server/frontends/lsp/ast/utility/FoldingRange.scala
Outdated
Show resolved
Hide resolved
src/main/scala/viper/server/frontends/lsp/ViperServerService.scala
Outdated
Show resolved
Hide resolved
src/main/scala/viper/server/frontends/lsp/ViperServerService.scala
Outdated
Show resolved
Hide resolved
src/main/scala/viper/server/frontends/lsp/ViperServerService.scala
Outdated
Show resolved
Hide resolved
Co-authored-by: Linard Arquint <ArquintL@users.noreply.github.com>
@ArquintL come chat about the remaining two points |
@rayman2000 done with the review, happy to merge if you're ready |
No description provided.