diff --git a/supervisor/__main__.py b/supervisor/__main__.py index 17dc292e3..6e2417690 100644 --- a/supervisor/__main__.py +++ b/supervisor/__main__.py @@ -13,7 +13,7 @@ zlib_fast.enable() # pylint: disable=wrong-import-position from supervisor import bootstrap # noqa: E402 -from supervisor.utils.blockbuster import activate_blockbuster # noqa: E402 +from supervisor.utils.blockbuster import BlockBusterManager # noqa: E402 from supervisor.utils.logging import activate_log_queue_handler # noqa: E402 # pylint: enable=wrong-import-position @@ -55,7 +55,7 @@ if __name__ == "__main__": coresys = loop.run_until_complete(bootstrap.initialize_coresys()) loop.set_debug(coresys.config.debug) if coresys.config.detect_blocking_io: - activate_blockbuster() + BlockBusterManager.activate() loop.run_until_complete(coresys.core.connect()) loop.run_until_complete(bootstrap.supervisor_debugger(coresys)) diff --git a/supervisor/api/supervisor.py b/supervisor/api/supervisor.py index 294451507..c79f88f42 100644 --- a/supervisor/api/supervisor.py +++ b/supervisor/api/supervisor.py @@ -49,11 +49,7 @@ from ..const import ( from ..coresys import CoreSysAttributes from ..exceptions import APIError from ..store.validate import repositories -from ..utils.blockbuster import ( - activate_blockbuster, - blockbuster_enabled, - deactivate_blockbuster, -) +from ..utils.blockbuster import BlockBusterManager from ..utils.sentry import close_sentry, init_sentry from ..utils.validate import validate_timezone from ..validate import version_tag, wait_boot @@ -110,7 +106,7 @@ class APISupervisor(CoreSysAttributes): ATTR_DEBUG_BLOCK: self.sys_config.debug_block, ATTR_DIAGNOSTICS: self.sys_config.diagnostics, ATTR_AUTO_UPDATE: self.sys_updater.auto_update, - ATTR_DETECT_BLOCKING_IO: blockbuster_enabled(), + ATTR_DETECT_BLOCKING_IO: BlockBusterManager.is_enabled(), ATTR_COUNTRY: self.sys_config.country, # Depricated ATTR_WAIT_BOOT: self.sys_config.wait_boot, @@ -180,10 +176,10 @@ class APISupervisor(CoreSysAttributes): detect_blocking_io = DetectBlockingIO.ON if detect_blocking_io == DetectBlockingIO.ON: - activate_blockbuster() + BlockBusterManager.activate() elif detect_blocking_io == DetectBlockingIO.OFF: self.sys_config.detect_blocking_io = False - deactivate_blockbuster() + BlockBusterManager.deactivate() # Deprecated if ATTR_WAIT_BOOT in body: diff --git a/supervisor/utils/blockbuster.py b/supervisor/utils/blockbuster.py index 2657c3176..655bd32ad 100644 --- a/supervisor/utils/blockbuster.py +++ b/supervisor/utils/blockbuster.py @@ -1,6 +1,5 @@ """Activate and deactivate blockbuster for finding blocking I/O.""" -from functools import cache import logging from blockbuster import BlockBuster @@ -8,28 +7,31 @@ from blockbuster import BlockBuster _LOGGER: logging.Logger = logging.getLogger(__name__) -@cache -def _get_blockbuster() -> BlockBuster: - """Get blockbuster instance.""" - return BlockBuster() +class BlockBusterManager: + """Manage BlockBuster instance.""" + _instance: BlockBuster | None = None -def blockbuster_enabled() -> bool: - """Return true if blockbuster detection is enabled.""" - blockbuster = _get_blockbuster() - # We activate all or none so just check the first one - for _, fn in blockbuster.functions.items(): - return fn.activated - return False + @classmethod + def is_enabled(cls): + """Return true if blockbuster detection is enabled.""" + if cls._instance is None: + return False + for _, fn in cls._instance.functions.items(): + return fn.activated + return False + @classmethod + def activate(cls): + """Activate blockbuster detection.""" + _LOGGER.info("Activating BlockBuster blocking I/O detection") + if cls._instance is None: + cls._instance = BlockBuster() + cls._instance.activate() -def activate_blockbuster() -> None: - """Activate blockbuster detection.""" - _LOGGER.info("Activating BlockBuster blocking I/O detection") - _get_blockbuster().activate() - - -def deactivate_blockbuster() -> None: - """Deactivate blockbuster detection.""" - _LOGGER.info("Deactivating BlockBuster blocking I/O detection") - _get_blockbuster().deactivate() + @classmethod + def deactivate(cls): + """Deactivate blockbuster detection.""" + _LOGGER.info("Deactivating BlockBuster blocking I/O detection") + if cls._instance: + cls._instance.deactivate()