Skip to content

Commit 89fa5c9

Browse files
agnerssairon
andauthored
Avoid initializing Blockbuster on Supervisor info call (#5901)
* Avoid initializing Blockbuster on Supervisor info call Instead of creating an instance of Blockbuster to simply check if Bluckbuster is enabled, use a global variable to store the instance of Blockbuster and only initialize it when needed. This avoids unnecessary initialization of Blockbuster when it is not required. * Update supervisor/utils/blockbuster.py Co-authored-by: Jan Čermák <sairon@users.noreply.github.com> * Fix merge and rename singleton class to BlockBusterManager * Fix pytest --------- Co-authored-by: Jan Čermák <sairon@users.noreply.github.com>
1 parent 73069b6 commit 89fa5c9

File tree

3 files changed

+34
-36
lines changed

3 files changed

+34
-36
lines changed

supervisor/__main__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
# pylint: disable=wrong-import-position
1515
from supervisor import bootstrap # noqa: E402
16-
from supervisor.utils.blockbuster import activate_blockbuster # noqa: E402
16+
from supervisor.utils.blockbuster import BlockBusterManager # noqa: E402
1717
from supervisor.utils.logging import activate_log_queue_handler # noqa: E402
1818

1919
# pylint: enable=wrong-import-position
@@ -55,7 +55,7 @@ def run_os_startup_check_cleanup() -> None:
5555
coresys = loop.run_until_complete(bootstrap.initialize_coresys())
5656
loop.set_debug(coresys.config.debug)
5757
if coresys.config.detect_blocking_io:
58-
activate_blockbuster()
58+
BlockBusterManager.activate()
5959
loop.run_until_complete(coresys.core.connect())
6060

6161
loop.run_until_complete(bootstrap.supervisor_debugger(coresys))

supervisor/api/supervisor.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,7 @@
4949
from ..coresys import CoreSysAttributes
5050
from ..exceptions import APIError
5151
from ..store.validate import repositories
52-
from ..utils.blockbuster import (
53-
activate_blockbuster,
54-
blockbuster_enabled,
55-
deactivate_blockbuster,
56-
)
52+
from ..utils.blockbuster import BlockBusterManager
5753
from ..utils.sentry import close_sentry, init_sentry
5854
from ..utils.validate import validate_timezone
5955
from ..validate import version_tag, wait_boot
@@ -110,7 +106,7 @@ async def info(self, request: web.Request) -> dict[str, Any]:
110106
ATTR_DEBUG_BLOCK: self.sys_config.debug_block,
111107
ATTR_DIAGNOSTICS: self.sys_config.diagnostics,
112108
ATTR_AUTO_UPDATE: self.sys_updater.auto_update,
113-
ATTR_DETECT_BLOCKING_IO: blockbuster_enabled(),
109+
ATTR_DETECT_BLOCKING_IO: BlockBusterManager.is_enabled(),
114110
ATTR_COUNTRY: self.sys_config.country,
115111
# Depricated
116112
ATTR_WAIT_BOOT: self.sys_config.wait_boot,
@@ -180,10 +176,10 @@ async def options(self, request: web.Request) -> None:
180176
detect_blocking_io = DetectBlockingIO.ON
181177

182178
if detect_blocking_io == DetectBlockingIO.ON:
183-
activate_blockbuster()
179+
BlockBusterManager.activate()
184180
elif detect_blocking_io == DetectBlockingIO.OFF:
185181
self.sys_config.detect_blocking_io = False
186-
deactivate_blockbuster()
182+
BlockBusterManager.deactivate()
187183

188184
# Deprecated
189185
if ATTR_WAIT_BOOT in body:

supervisor/utils/blockbuster.py

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,37 @@
11
"""Activate and deactivate blockbuster for finding blocking I/O."""
22

3-
from functools import cache
43
import logging
54

65
from blockbuster import BlockBuster
76

87
_LOGGER: logging.Logger = logging.getLogger(__name__)
98

109

11-
@cache
12-
def _get_blockbuster() -> BlockBuster:
13-
"""Get blockbuster instance."""
14-
return BlockBuster()
15-
16-
17-
def blockbuster_enabled() -> bool:
18-
"""Return true if blockbuster detection is enabled."""
19-
blockbuster = _get_blockbuster()
20-
# We activate all or none so just check the first one
21-
for _, fn in blockbuster.functions.items():
22-
return fn.activated
23-
return False
24-
25-
26-
def activate_blockbuster() -> None:
27-
"""Activate blockbuster detection."""
28-
_LOGGER.info("Activating BlockBuster blocking I/O detection")
29-
_get_blockbuster().activate()
30-
31-
32-
def deactivate_blockbuster() -> None:
33-
"""Deactivate blockbuster detection."""
34-
_LOGGER.info("Deactivating BlockBuster blocking I/O detection")
35-
_get_blockbuster().deactivate()
10+
class BlockBusterManager:
11+
"""Manage BlockBuster instance."""
12+
13+
_instance: BlockBuster | None = None
14+
15+
@classmethod
16+
def is_enabled(cls):
17+
"""Return true if blockbuster detection is enabled."""
18+
if cls._instance is None:
19+
return False
20+
for _, fn in cls._instance.functions.items():
21+
return fn.activated
22+
return False
23+
24+
@classmethod
25+
def activate(cls):
26+
"""Activate blockbuster detection."""
27+
_LOGGER.info("Activating BlockBuster blocking I/O detection")
28+
if cls._instance is None:
29+
cls._instance = BlockBuster()
30+
cls._instance.activate()
31+
32+
@classmethod
33+
def deactivate(cls):
34+
"""Deactivate blockbuster detection."""
35+
_LOGGER.info("Deactivating BlockBuster blocking I/O detection")
36+
if cls._instance:
37+
cls._instance.deactivate()

0 commit comments

Comments
 (0)