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)