-
-
Notifications
You must be signed in to change notification settings - Fork 106
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
pygls does not handle async user shutdown
handler correctly
#433
Comments
I think I have an idea that will fix this, but it will probably have to go into #418. If we allow pygls' built-in features to Not only would this fix this issue, but it might help with #381, where pygls can do some initial setup e.g. initialize the workspace, set client capabilities on the server object etc. and then |
This is likely not enough to fully resolve the shutdown issue (as that requires a fix in `pygls`[1]) but at least now the server will make an attempt to shut itself down. [1]: openlawlibrary/pygls#433
This is likely not enough to fully resolve the shutdown issue (as that requires a fix in `pygls`[1]) but at least now the server will make an attempt to shut itself down. [1]: openlawlibrary/pygls#433
The most recent release of pytest-lsp now surfaces the above issue in the test suite. So that esbonio is not blocked on a fix, wrap the call to `shutdown_session` in `asyncio.wait_for` and ignore the timeout error.
The most recent release of pytest-lsp now surfaces the above issue in the test suite. So that esbonio is not blocked on a fix, wrap the call to `shutdown_session` in `asyncio.wait_for` and ignore the timeout error.
The most recent release of pytest-lsp now surfaces the above issue in the test suite. So that esbonio is not blocked on a fix, wrap the call to `shutdown_session` in `asyncio.wait_for` and ignore the timeout error.
The underlying cause of openlawlibrary#433 is that pygls' current implementation of builtin feature handlers cannot guarantee that an async user handler will finish executing before pygls responds with the answer generated from the builtin handler. This commit adds support for another execution model, generators. A generator handler can yield to another sub-handler method like so ``` yield handler_func, args, kwargs ``` The `JsonRPCProtocol` class with then schedule the execution of `handler_func(*args, **kwargs)` as if it were a normal handler function (meaning `handler_func could be async, threaded, sync or a generator itself!) The result of the sub-handler is then sent back into the generator handler allowing the top-level handler to continue and even make use of the result! This gives pygls' built-in handlers much greater control over exactly when a user handler is called, allowing us to fix openlawlibrary#433 and opens up a lot other exciting possibilities! This also removes the need for the `LSPMeta` metaclass, so it and the corresponding module have been deleted.
If I register an async handler for the
shutdown
request, pygls does not guarantee that it will finish executing before responding to the client. This often leads to the client sending theexit
notification and pygls callingsys.exit()
before my code cleaned up everything it needs to.I'm finding this is leading to a lot of orphaned
esbonio
processes hanging around on my machine! 😅I think the issue is down to how pygls handles the user registering features that "shadow" built in features.
pygls/pygls/protocol/lsp_meta.py
Lines 15 to 29 in d3a1421
If we look at how
_execute_notification
is implementedpygls/pygls/protocol/json_rpc.py
Lines 144 to 153 in d3a1421
It uses
asyncio.ensure_future
to schedule the coroutine to be executed, but then will return almost immediately - meaning there's no guarantee it will complete before pygls responds to the client.The text was updated successfully, but these errors were encountered: