Changing the frequency at which we update worktrees highlighted a
problem in the randomized tests that was causing clients to receive
a definition to a worktree *before* observing the registration of
the worktree itself. This was most likely caused by #1224 because
the scenario that pull request enabled was the following:
- Guest requests a definition pointing to a non-existant worktree
- Server forwards the request to the host
- Host sends an `UpdateProject` message
- Host sends a response to the definition request
- Server observes the `UpdateProject` message and tries to acquire
the store
- Given that we're waiting, the server goes ahead to process the
response for the definition request, responding *before*
`UpdateProject` is forwarded
- Server finally forwards `UpdateProject` to the guest
This commit ensures that, after forwarding a project request and getting a
response, we acquire a lock to the store again to ensure the project still
exists. This has the effect of ordering the forwarded request *after* any
message that was received prior to the response and for which we are still
waiting to acquire a lock to the store.
With the new version of rust-analyzer, we were seeing stray `WorkDoneProgress::End`
messages that create an imbalance in the `pending_diagnostic_updates` that never
resolves. This was causing the diagnostic status bar item to never update because
we wouldn't emit `DiskBasedDiagnosticsStarted` nor `DiskBasedDiagnosticsFinished`.
This commit fixes the above situation by only acknowledging progress report for tokens
that have explicitly been created via the `WorkDoneProgressCreate` request, as stated
by the protocol.
In addition to that, we are replacing the `pending_diagnostic_updates: isize` with
a `has_pending_diagnostic_updates: bool`. We added it at some point to prevent a similar
issue where we would observe begin/end reports in a seemingly random order, which would cause
us to permanently display a `checking...` message in the status bar. I believe this commit
fixes that as well because the `isize` was just a less general solution for the same
underlying issue. As the protocol states: "the token provided in the create request should
only be used once (e.g. only one begin, many report and one end notification should be sent
to it)."
This lets us use the group id as the key for an `ElementState`, which
fixes a panic that would occur in project diagnostics when opening it
while there were multiple diagnostic groups with the same id.