Skip to content

Avoid blocking when prepping pragmas for inlay#4882

Draft
crtschin wants to merge 1 commit intohaskell:masterfrom
crtschin:crtschin/inlay-latencies
Draft

Avoid blocking when prepping pragmas for inlay#4882
crtschin wants to merge 1 commit intohaskell:masterfrom
crtschin:crtschin/inlay-latencies

Conversation

@crtschin
Copy link
Copy Markdown
Collaborator

@crtschin crtschin commented Apr 3, 2026

Closes #4877.

One of the inlay hint providers blocked on preparing to edit pragmas. This PR creates a *WithStaleFast version of getFirstPragma, and uses it in the inlay handler.

Before
"textDocument/inlayHint": {
  "count": 469,
  "p50_ms": 126.304996,
  "p95_ms": 6388.946637,
  "p99_ms": 9595.631002999999
},
After
"textDocument/inlayHint": {
  "count": 469,
  "p50_ms": 3.634777,
  "p95_ms": 320.070144,
  "p99_ms": 784.9861259999999
},

@fendor
Copy link
Copy Markdown
Collaborator

fendor commented Apr 7, 2026

What about the other uses of getFirstPragma, aren't they also problematic?

I thought that lsp is async, just because the inlay hint request blocks doesn't mean we can't respond to other request a non-block way?

@crtschin
Copy link
Copy Markdown
Collaborator Author

crtschin commented Apr 7, 2026

What about the other uses of getFirstPragma, aren't they also problematic?

I don't actually know. I assume in some cases we'd want to have the latest version (I saw references to Rope while perusing this bit of the code). Might actually be that getFirstPragmaFast is always fine to use, I'd have to check.

I thought that lsp is async, just because the inlay hint request blocks doesn't mean we can't respond to other request a non-block way?

For requests it is! Notifications aren't, which is the topic of this PR. You're right though that latency here isn't that big of a problem. I think it would still be nice to have inlay's be snappy, as it reduces text jumping around in the editor.

Comment on lines +69 to +70
fileContents <- fmap (snd . fst) $ useWithStaleFastE GetFileContents nfp
pure $ getNextPragmaInfo sessionDynFlags fileContents
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels risky, if the file contents are truly outdated, the pragma info is going to be displayed incorrectly in the buffer. Are such inlay hints useful at all?

I think it is always save to wait for the result of getFileContents

@fendor
Copy link
Copy Markdown
Collaborator

fendor commented Apr 7, 2026

I think it would still be nice to have inlay's be snappy, as it reduces text jumping around in the editor.

Aren't they snappy already? Afaict, this delay is caused by the request handler waiting for the session setup to complete, which can easily take a long time. If we are not waiting, we are simply producing the empty list and the client needs to retry at some point, asking whether the inlay hints have updated.
I am curious, are the inlay hints still shown at all? E.g., if you simply start HLS and do not touch it at all until the session is fully initialised, are the inlay hints still shown? Is VSCode just proactively fetching them multiple times even though the document doesn't change?

Once the session is initialised, I think inlay hints are already snappy and this change should only make a difference, if we are changing the session (e.g., load a new component, startup, or editing the .cabal file)?

@crtschin
Copy link
Copy Markdown
Collaborator Author

crtschin commented Apr 7, 2026

Aren't they snappy already? Afaict, this delay is caused by the request handler waiting for the session setup to complete, which can easily take a long time. If we are not waiting, we are simply producing the empty list and the client needs to retry at some point, asking whether the inlay hints have updated.
...
Once the session is initialised, I think inlay hints are already snappy and this change should only make a difference, if we are changing the session (e.g., load a new component, startup, or editing the .cabal file)?

Appreciate the quick responses!

Yeah that's correct. The vast majority of inlay requests are very quick, only lagging very seldomly, which is what this PR tries to resolve. Though you make a very good point that getFirstPragmaFast is risky as it deals with stale data. I still have it on my list to double check what the consequences of that are.

I am curious, are the inlay hints still shown at all? E.g., if you simply start HLS and do not touch it at all until the session is fully initialised, are the inlay hints still shown? Is VSCode just proactively fetching them multiple times even though the document doesn't change?

I use helix, but I think it's quite similar. On master on the initial load, until the session is initialized the file doesn't show any inlays. Once the session's loaded it's fine. If I then edit the cabal file. The inlay output doesn't change and is frozen; if I change an import (ex. introducing a typo in a unqualified import), the inlay keeps being there (like ghost text) until the session's loaded in again.

With the changes in this PR, when the session is reloaded due to changing the cabal file, the inlay keeps being up to date, removing the invalid inlay when I introduce a typo in the import.

Helix specifically sends inlay requests when the editor is idle, as well as when the document changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

High tail latencies when doing textDocument/inlayHint requests

2 participants