GNU bug report logs -
#77588
Catastrophic slowdown in eglot via `flymake-diag-region'
Previous Next
Reported by: JD Smith <jdtsmith <at> gmail.com>
Date: Sun, 6 Apr 2025 22:51:02 UTC
Severity: normal
Done: João Távora <joaotavora <at> gmail.com>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
> On Apr 8, 2025, at 5:00 PM, João Távora <joaotavora <at> gmail.com> wrote:
>
>>
>> Maybe I am missing something, but if the push diagnostics and
>> didChange cross paths, I could see how the latter could be out of
>> date.
>
> Indeed, but they don't cross paths, at least not on virtually all
> servers that I know of. Servers on a "push diagnostics" model operate
> by sending at most 1 publishDiagnostics notification _after_ receiiving
> a didChange. Which makes sense. You're notified of some changes V1,
> you do some calculations, and you publish your results. If you operate
> asynchronously and during that time you get another notification of
> changes V2, you probably have throw most work out (certainly don't
> publish it).
>
> If you supply the Eglot events log to your server session we can check
> what's happening. I have used basedpyright+eglot in the past though,
> and I never noticed any problems (doesn't mean they can't or weren't
> happening under the hood, but I certainly didn't experience any
> catastrophic slowdown).
This is an interesting point. Here's an event log: [1]. I modified the old notifier to simply alert when versions didn't match. It reports:
Diagnostics version mismatch 28 received, 29 current
In the log, you can see the following pattern:
[jsonrpc] e[19:15:32.870] --> textDocument/inlayHint[107]
[jsonrpc] e[19:15:32.905] <-- textDocument/inlayHint[107]
[jsonrpc] e[19:15:33.079] --> textDocument/didChange ; Version 29 change sent
[jsonrpc] e[19:15:33.079] --> textDocument/completion[108]
[jsonrpc] e[19:15:33.383] --> textDocument/inlayHint[109]
[jsonrpc] e[19:15:33.446] <-- textDocument/publishDiagnostics ; Version 28 diagnostics received
[jsonrpc] e[19:15:33.800] --> textDocument/signatureHelp[110]
[jsonrpc] e[19:15:33.801] --> textDocument/hover[111]
[jsonrpc] e[19:15:33.801] --> textDocument/documentHighlight[112]
[jsonrpc] e[19:15:33.807] <-- textDocument/completion[108]
[jsonrpc] e[19:15:33.809] <-- textDocument/inlayHint[109]
[jsonrpc] e[19:15:34.095] <-- textDocument/publishDiagnostics ; Version 29 diagnostics received
I.e. v28 diagnostics are received *after* v29 didChange is sent. Up to 50% of the updates have this version mismatch. Is it significant that the publishDiagnostics is "nested" inside a completion? Note that it also happens (though less frequently) even when typing a multiple line comment, always shortly after a newline is entered. I agree this is strange: basepyright should drop the v28 update like a rock.
Also during these pauses, I found that end-of-thing often (but not always) errors out:
1 -> (end-of-thing symbol)
1 <- end-of-thing: !non-local\ exit!
======================================================================
1 -> (end-of-thing sexp)
1 <- end-of-thing: !non-local\ exit!
======================================================================
1 -> (end-of-thing symbol)
1 <- end-of-thing: 306546
======================================================================
1 -> (end-of-thing sexp)
1 <- end-of-thing: !non-local\ exit!
======================================================================
1 -> (end-of-thing symbol)
1 <- end-of-thing: 306546
======================================================================
1 -> (end-of-thing sexp)
1 <- end-of-thing: !non-local\ exit!
======================================================================
I think this explains why my slow-down isn't as bad here: end-of-thing is now *crashing* (inside ignore-errors). Not the most useful speedup to be sure, and not sure what changed, probably a parsing difference in the file.
Repeating that command by hand shows the real error:
Debugger entered--Lisp error: (error "No sexp here")
signal(error ("No sexp here"))
error("No %s here" sexp)
#<subr end-of-thing>(sexp)
apply(#<subr end-of-thing> sexp)
#f(compiled-function (body &rest args) #<bytecode 0x1dcd258a89e09bb5>)(#<subr end-of-thing> sexp)
apply(#f(compiled-function (body &rest args) #<bytecode 0x1dcd258a89e09bb5>) #<subr end-of-thing> sexp)
end-of-thing(sexp)
eval((end-of-thing 'sexp) t)
#f(compiled-function () #<bytecode 0x12f7d3ddabb81c2a>)()
#f(compiled-function () #<bytecode -0x5db3e1955cb81d1>)()
handler-bind-1(#f(compiled-function () #<bytecode -0x5db3e1955cb81d1>) (error) eval-expression--debug)
eval-expression((end-of-thing 'sexp) nil nil 127)
funcall-interactively(eval-expression (end-of-thing 'sexp) nil nil 127)
call-interactively(eval-expression nil nil)
command-execute(eval-expression)
[1] https://gist.githubusercontent.com/jdtsmith/a604c1e99f98f48da4d76f0abf07aedc/raw/0eb71ea878c70dc4d44afe56e44731d7dd135e19/event-buffer.txt
This bug report was last modified 44 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.