From 27d5ac537f3d449877bbaec1913c80208e0579a7 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 6 Nov 2023 12:32:23 +1000 Subject: [PATCH] Non-blocking checksums computation when server starts. Fixes #2228 --- gns3server/web/web_server.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/gns3server/web/web_server.py b/gns3server/web/web_server.py index 7d14063a..fd116b39 100644 --- a/gns3server/web/web_server.py +++ b/gns3server/web/web_server.py @@ -29,6 +29,7 @@ import functools import time import atexit import weakref +import concurrent.futures # Import encoding now, to avoid implicit import later. # Implicit import within threads may cause LookupError when standard library is in a ZIP @@ -38,7 +39,7 @@ from .route import Route from ..config import Config from ..compute import MODULES from ..compute.port_manager import PortManager -from ..compute.qemu import Qemu +from ..utils.images import list_images from ..controller import Controller # do not delete this import @@ -87,6 +88,8 @@ class WebServer: except (RuntimeError, OSError, asyncio.CancelledError) as e: log.critical("Could not start the server: {}".format(e)) return False + except KeyboardInterrupt: + return False return True async def reload_server(self): @@ -230,16 +233,27 @@ class WebServer: atexit.register(close_asyncio_loop) + async def _compute_image_checksums(self): + """ + Compute image checksums. + """ + + loop = asyncio.get_event_loop() + with concurrent.futures.ProcessPoolExecutor(max_workers=1) as pool: + log.info("Computing image checksums...") + await loop.run_in_executor(pool, list_images, "qemu") + log.info("Finished computing image checksums") + async def _on_startup(self, *args): """ Called when the HTTP server start """ await Controller.instance().start() - # Because with a large image collection - # without md5sum already computed we start the - # computing with server start - asyncio.ensure_future(Qemu.instance().list_images()) + + # Start computing checksums now because it can take a long time + # for a large image collection + await self._compute_image_checksums() def run(self): """