From 927f0b5017e24a445c3fab41b83cb475b1b702b6 Mon Sep 17 00:00:00 2001 From: spacemanspiff2007 <10754716+spacemanspiff2007@users.noreply.github.com> Date: Fri, 27 Sep 2024 10:33:22 +0200 Subject: [PATCH] Fixed issue with profiler --- src/HABApp/__version__.py | 2 +- .../wrapped_function/wrapped_thread.py | 41 +++++-------------- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/src/HABApp/__version__.py b/src/HABApp/__version__.py index 868b4cbf..528144c3 100644 --- a/src/HABApp/__version__.py +++ b/src/HABApp/__version__.py @@ -10,4 +10,4 @@ # Development versions contain the DEV-COUNTER postfix: # - 24.01.0.DEV-1 -__version__ = '24.09.0.DEV-2' +__version__ = '24.09.0.DEV-3' diff --git a/src/HABApp/core/internals/wrapped_function/wrapped_thread.py b/src/HABApp/core/internals/wrapped_function/wrapped_thread.py index 1e57c889..341b366f 100644 --- a/src/HABApp/core/internals/wrapped_function/wrapped_thread.py +++ b/src/HABApp/core/internals/wrapped_function/wrapped_thread.py @@ -1,17 +1,12 @@ from __future__ import annotations -import io -from collections.abc import Callable from concurrent.futures import ThreadPoolExecutor -from cProfile import Profile -from pstats import SortKey, Stats from threading import Lock from time import monotonic from typing import TYPE_CHECKING, Any, Final from typing_extensions import override -from HABApp.core.asyncio import async_context from HABApp.core.const import loop from HABApp.core.internals import Context, ContextProvidingObj from HABApp.core.internals.wrapped_function.base import P, R, WrappedFunctionBase, default_logger @@ -19,6 +14,7 @@ if TYPE_CHECKING: import logging + from collections.abc import Callable POOL: ThreadPoolExecutor | None = None @@ -27,8 +23,10 @@ def create_thread_pool(count: int) -> None: global POOL, POOL_THREADS - assert isinstance(count, int) - assert count > 0 + + if not isinstance(count, int) or count <= 0: + msg = 'Thread count must be a positive integer' + raise ValueError(msg) default_logger.debug(f'Starting thread pool with {count:d} threads!') @@ -94,16 +92,12 @@ def run(self): parent.log.warning(f'Starting of {parent.name} took too long: {self.dur_start:.2f}s. ' f'Maybe there are not enough threads?') - # start profiler - pr = Profile() - pr.enable() + # Profiler does not work + # https://github.com/python/cpython/issues/124656 # Execute the function ret = self.func_obj(*self.func_args, **self.func_kwargs) - # disable profiler - pr.disable() - # log warning if execution takes too long self.dur_run = monotonic() - ts_start @@ -111,14 +105,6 @@ def run(self): parent.log.warning(f'{self.usage_high}/{POOL_THREADS} threads have been in use and ' f'execution of {parent.name} took too long: {self.dur_run:.2f}s') - s = io.StringIO() - ps = Stats(pr, stream=s).sort_stats(SortKey.CUMULATIVE) - ps.print_stats(0.1) # limit to output to 10% of the lines - - for line in s.getvalue().splitlines()[4:]: # skip the amount of calls and "Ordered by:" - if line: - parent.log.warning(line) - except Exception as e: self.parent.process_exception(e, *self.func_args, **self.func_kwargs) return None @@ -132,15 +118,15 @@ def run(self): class WrappedThreadFunction(WrappedFunctionBase[P, R]): def __init__(self, func: Callable[P, R], - warn_too_long=True, + warn_too_long: bool = True, name: str | None = None, logger: logging.Logger | None = None, context: Context | None = None) -> None: super().__init__(name=name, func=func, logger=logger, context=context) - self.func = func - self.warn_too_long: bool = warn_too_long + self.func: Final = func + self.warn_too_long: Final = warn_too_long @override def run(self, *args: P.args, **kwargs: P.kwargs) -> None: @@ -152,10 +138,5 @@ def run(self, *args: P.args, **kwargs: P.kwargs) -> None: @override async def async_run(self, *args: P.args, **kwargs: P.kwargs) -> R | None: - token = async_context.set('WrappedThreadFunction') - pool_func = PoolFunc(self, self.func, args, kwargs, context=self._habapp_ctx) - ret = await loop.run_in_executor(POOL, pool_func.run) - - async_context.reset(token) - return ret + return await loop.run_in_executor(POOL, pool_func.run)