-
-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Pygls handles requests that are known to be cancelled #517
Comments
Thank you for using Pygls! 🥳 So you're actively using that workaround at the moment with success? We're actually in the middle of open alpha for migrating to v2 of Pygls. Have you tried it? It's on the main branch, we have a migration guide. It has some notable changes in the area you're talking about. We'd be very much open to PRs, either targeting the current release or current v2 alpha. I'm not familiar with the new code so it might be some time before I could be in a position to contribute a fix. |
@tombh I have a PR in our repo (posit-dev/positron#6219) and a unit test but haven't validated it end to end. I haven't tried v2 yet. We had to make a few asyncio/threading changes to I unfortunately can't promise a PR right now, but might be able to look into it when we upgrade to v2. |
The main thing to try would be trying to offload the heavy computation from the main thread so that the main loop has chance to reach the cancel notifications and process them... I see from your linked PR that you found the You could also try an async handler wrapping a subprocess, (which appears to work well for me in Something to note, when running the server with |
This is a workaround for openlawlibrary/pygls#517 until it's fixed upstream. ### Release Notes #### New Features - N/A #### Bug Fixes - Fixed a Python language server performance issue where a slow request could hang the server. ### QA Notes I'm not sure how to reproduce this, but nothing should break.
@alcarney Thank you for the tips! Using a subprocess won't be easy since we'd need to read some data across processes, but we'll try |
Firstly, hello and thank you for your awesome work on pygls! 🥳 We've been using it (via
jedi-language-server
) over at Positron.One of our users recently encountered an interesting pygls performance issue where a very slow request causes a buildup of cancelled requests that still get processed unnecessarily by the server. It would be great if pygls could skip requests that are cancelled before it starts handling them.
Details
The client, Positron in this case, starts with a
textDocument/hover
request.The client times out waiting for the server to respond to the request, sends a
$/cancelRequest
, and tries a newtextDocument/hover
. It may do this multiple times all while the first request is still being handled. If the handler is synchronous (as are mostjedi-language-server
handlers) and the request takes very long (30 seconds in our user's case) it's possible for a pretty large queue to build up (~70 messages in our case), many of which are cancellations of the other messages (~30 cancellations in our case, meaning that ~60/70 messages needn't be handled).However, pygls handles each message and then handles its cancellation (leading to warning logs
Cancel notification for unknown message id
). It could take very long for all of these cancelled messages to be handled, all while the user sees no response in the UI because the client thinks they've cancelled everything (the buildup wasn't resolved after ~90 additional seconds in our case).I think this is worth optimizing in pygls. If there's also a way for us to configure our handlers to avoid this situation entirely, any pointers would be appreciated!
Workaround
I intend on overriding
LanguageServerProtocol
as follows as a temporary workaround:The text was updated successfully, but these errors were encountered: