From 9f9f2bea0e265d87a335ec059d051c6c1c837652 Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Sat, 10 Feb 2024 18:59:27 +0000 Subject: [PATCH 1/3] esbonio: Move pyright config into `pyproject.toml` --- lib/esbonio/pyproject.toml | 7 +++++++ lib/esbonio/pyrightconfig.json | 3 --- 2 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 lib/esbonio/pyrightconfig.json diff --git a/lib/esbonio/pyproject.toml b/lib/esbonio/pyproject.toml index 510126a2b..0e7562d09 100644 --- a/lib/esbonio/pyproject.toml +++ b/lib/esbonio/pyproject.toml @@ -77,6 +77,13 @@ mypy_path = "$MYPY_CONFIG_FILE_DIR" explicit_package_bases = true check_untyped_defs = true +[tool.pyright] +venv = ".env" +include = ["esbonio"] + +pythonVersion = "3.8" +pythonPlatform = "All" + [tool.towncrier] filename = "CHANGES.md" directory = "changes/" diff --git a/lib/esbonio/pyrightconfig.json b/lib/esbonio/pyrightconfig.json deleted file mode 100644 index 0622ac86c..000000000 --- a/lib/esbonio/pyrightconfig.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "venv": ".env" -} From bc23a36103600cb1584b17577544898183a1c3a5 Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Sat, 10 Feb 2024 19:02:18 +0000 Subject: [PATCH 2/3] lsp: Allow features to register shutdown handlers --- lib/esbonio/esbonio/server/feature.py | 3 +++ lib/esbonio/esbonio/server/server.py | 3 +++ lib/esbonio/esbonio/server/setup.py | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/lib/esbonio/esbonio/server/feature.py b/lib/esbonio/esbonio/server/feature.py index c2fb0d5cd..517c7a9f7 100644 --- a/lib/esbonio/esbonio/server/feature.py +++ b/lib/esbonio/esbonio/server/feature.py @@ -57,6 +57,9 @@ def initialize(self, params: types.InitializeParams): def initialized(self, params: types.InitializedParams): """Called when the ``initialized`` notification is received.""" + def shutdown(self, params: None): + """Called when the server is instructed to ``shutdown`` by the client.""" + def document_change(self, params: types.DidChangeTextDocumentParams): """Called when a text document is changed.""" diff --git a/lib/esbonio/esbonio/server/server.py b/lib/esbonio/esbonio/server/server.py index 03d20ac94..ff2c7adbd 100644 --- a/lib/esbonio/esbonio/server/server.py +++ b/lib/esbonio/esbonio/server/server.py @@ -123,6 +123,9 @@ async def initialized(self, params: types.InitializedParams): ) self._ready.set_result(True) + def lsp_shutdown(self, params: None): + """Called when the server is instructed to ``shutdown`` by the client.""" + def load_extension(self, name: str, setup: Callable): """Load the given setup function as an extension. diff --git a/lib/esbonio/esbonio/server/setup.py b/lib/esbonio/esbonio/server/setup.py index ff15e0987..b2ea77596 100644 --- a/lib/esbonio/esbonio/server/setup.py +++ b/lib/esbonio/esbonio/server/setup.py @@ -57,6 +57,11 @@ async def on_initialized( await ls.initialized(params) await call_features(ls, "initialized", params) + @server.feature(types.SHUTDOWN) + async def on_shutdown(ls: EsbonioLanguageServer, params: None): + ls.lsp_shutdown(params) + await call_features(ls, "shutdown", params) + @server.feature(types.TEXT_DOCUMENT_DID_CHANGE) async def on_document_change( ls: EsbonioLanguageServer, params: types.DidChangeTextDocumentParams From c127bf7127ef7248978cdae2b79a33b812aafe51 Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Sat, 10 Feb 2024 19:03:29 +0000 Subject: [PATCH 3/3] lsp: Implement shutdown for `SphinxManager` and `PreviewManager` 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]: https://github.com/openlawlibrary/pygls/issues/433 --- .../features/preview_manager/__init__.py | 15 ++++++++++++ .../server/features/sphinx_manager/manager.py | 23 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/esbonio/esbonio/server/features/preview_manager/__init__.py b/lib/esbonio/esbonio/server/features/preview_manager/__init__.py index acc08a0b0..2eabbd4a9 100644 --- a/lib/esbonio/esbonio/server/features/preview_manager/__init__.py +++ b/lib/esbonio/esbonio/server/features/preview_manager/__init__.py @@ -1,5 +1,6 @@ import asyncio import logging +import sys from http.server import HTTPServer from http.server import SimpleHTTPRequestHandler from typing import Any @@ -92,6 +93,20 @@ def __init__(self, server: EsbonioLanguageServer, sphinx: SphinxManager): self._ws_server: Optional[WebviewServer] = None self._ws_task: Optional[asyncio.Task] = None + def shutdown(self, params: None): + """Called when the client instructs the server to ``shutdown``.""" + args = {} + if sys.version_info.minor > 8: + args["msg"] = "Server is shutting down." + + if self._http_server: + self.logger.debug("Shutting down preview HTTP server") + self._http_server.shutdown() + + if self._ws_task: + self.logger.debug("Shutting down preview WebSocket server") + self._ws_task.cancel(**args) + @property def preview_active(self) -> bool: """Return true if the preview is active. diff --git a/lib/esbonio/esbonio/server/features/sphinx_manager/manager.py b/lib/esbonio/esbonio/server/features/sphinx_manager/manager.py index c00759c0e..c44f637a8 100644 --- a/lib/esbonio/esbonio/server/features/sphinx_manager/manager.py +++ b/lib/esbonio/esbonio/server/features/sphinx_manager/manager.py @@ -2,6 +2,7 @@ import asyncio import inspect +import sys import typing import uuid from typing import Callable @@ -86,6 +87,26 @@ async def document_save(self, params: lsp.DidSaveTextDocumentParams): await self.trigger_build(uri) + async def shutdown(self, params: None): + """Called when the server is instructed to ``shutdown``.""" + + # Stop creating any new clients. + if self._client_creating and not self._client_creating.done(): + args = {} + if sys.version_info.minor > 8: + args["msg"] = "Server is shutting down" + + self.logger.debug("Aborting client creation") + self._client_creating.cancel(**args) + + # Stop any existing clients. + tasks = [] + for client in self.clients.values(): + self.logger.debug("Stopping SphinxClient: %s", client) + tasks.append(asyncio.create_task(client.stop())) + + await asyncio.gather(*tasks) + async def trigger_build_after(self, uri: Uri, app_id: str, delay: float): """Trigger a build for the given uri after the given delay.""" await asyncio.sleep(delay) @@ -217,7 +238,7 @@ async def start_progress(self, client: SphinxClient): return token = str(uuid.uuid4()) - self.logger.error("Starting progress: '%s'", token) + self.logger.debug("Starting progress: '%s'", token) try: await self.server.progress.create_async(token)