-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Fix hanging MessagesPoll.Poll
#4325
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
| response = self.HandleFuture( self._response_future, | ||
| display_message = False ) | ||
| # Non-blocking extraction since done() is True. We avoid HandleFuture() | ||
| # because it calls response.read() which blocks on large responses. |
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.
this code also calls response.read() so please can you explain in the comment and in detail in the PR description why this fixes the issue?
|
Thanks for the PR! I'm still a bit confused why this change actually fixes it though. I get that if there's a huge message we have to block to read it, but this code still has to read it and it's still going to run in the vim main thread. |
Codecov Report❌ Patch coverage is ❌ Your changes status has failed because you have indirect coverage changes. Learn more about Unexpected Coverage Changes and reasons for indirect coverage changes. Additional details and impacted files@@ Coverage Diff @@
## master #4325 +/- ##
==========================================
+ Coverage 75.29% 75.38% +0.09%
==========================================
Files 30 30
Lines 2898 2913 +15
==========================================
+ Hits 2182 2196 +14
- Misses 716 717 +1 🚀 New features to boost your workflow:
|
|
Sure, added it to the PR description and extended the code comment. |
| display_message = False ) | ||
| # Avoid HandleFuture() to prevent blocking in timer callbacks. | ||
| # HandleFuture() does: | ||
| # 1. Complex exception handling (UnknownExtraConf, DisplayServerException) |
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.
so? why is this a problem in this case? do we have a trivial/minimal repro case?
| # Avoid HandleFuture() to prevent blocking in timer callbacks. | ||
| # HandleFuture() does: | ||
| # 1. Complex exception handling (UnknownExtraConf, DisplayServerException) | ||
| # 2. User dialogs that can block waiting for input |
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.
No it doesn't, at least, not in any relevant codepath.
| # HandleFuture() does: | ||
| # 1. Complex exception handling (UnknownExtraConf, DisplayServerException) | ||
| # 2. User dialogs that can block waiting for input | ||
| # 3. Vim UI updates during callback execution |
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.
So does this code. I mean, that's its literal job : HandlePollResponse will do UI updates, that's what it's for.
| # 2. User dialogs that can block waiting for input | ||
| # 3. Vim UI updates during callback execution | ||
| # By extracting the response directly with minimal error handling, we avoid | ||
| # blocking vim's main thread. Note that response.read() is still technically |
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.
citation needed?
If response.done() is True then HandleFuture (which just calls JsonFromFuture) will just do the exact thing this code does, except this code skips HMAC validation, which is absolute Nope. Skipping HMAC validation is a security issue and we can't accept it.
I'm honestly not convinced by this change, and the explanation seems ... synthetic to me.
I'm willing to believe there is indeed an issue when there are very big notification messages (such as huge diagnostics) but I'd like to have a more convincing explanation and maybe the flame graph, profile, or whatever was mentioned in the description.
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.
Thank you for the detailed review. I'm sorry you're upset with a generated answer.
I didn't test the fix well enough. Most likely, I concluded it was fixed before the entire dataset was indexed by rust-analyzer, and it still freezes, but I didn't reproduce it before submitting the PR.
Here's the original flamegraph + perf.script data I used for it.
The second flamegraph looks similar, since I waited until the data was loaded. For the one that showed an improvement, I only have a flamegraph; the perf data has been overwritten.
I'll dig a bit deeper into it, but it looks like there's no easy solution.
Thank you for your time, and happy New Year 2026!
|
Sorry for submitting trash. There's no easy fix for this particular issue. |
|
Hey, no worries! Thanks for the contribution! Actually, you've provided some good data here. I have experienced something similar myself and I actually just remembered that I made a hack in my fork to work around it. The hack was to restrict the length of any given diagnostic range. IIRC the problem was adding text properties that spanned entire functions led to really really bad results client side. If I get some time I might try to reproduce and fix it. |
|
The repro is relatively trivial.
|
PR Prelude
Thank you for working on YCM! :)
Please complete these steps and check these boxes (by putting an
xinsidethe brackets) before filing your PR:
rationale for why I haven't.
actually perform all of these steps.
Why this change is necessary and useful
Vim hangs when editing Rust files with YCM + rust-analyzer. The PR fixes #4272.
MessagesPoll.Polluses blockingHandleFuture, that's why it happens. This causes the mainvimprocess to hang for a few seconds.HandleFuture()performs heavy synchronous operations:UnknownExtraConfprompts that block waiting for user input.DisplayServerException()status line updates.All of this runs synchronously in vim's main thread during timer callbacks, freezing the UI.
The fix still calls
response.read(), which is technically blocking I/O. However, this is acceptable because:read()afterdone()returnsTrue, meaning the HTTP response is completeread()just copies from the response buffer to memory, no actual network waitThis change is