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/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) 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 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" -}