From 3f56b1f3ef971d4e6123c54fdac23654bfd65cca Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Sun, 27 Oct 2019 10:00:01 +0800 Subject: [PATCH] mgr/diskprediction_cloud: refactor timeout() decorator * timeout() is never passed any parameter when being called, so let's remove the parameters list of "seconds" and "error_message" * use `getattr()` instead of `hasattr()` for retrieving the member variable of `self` * pass `self` to wrapper function explicitly. * return `func()` right away. * hardwire the error message of `TimeoutError` to "Timer expired", because - as neither errno.ETIME nor errno.ETIMEOUT is portable - the only caller of `TimeoutError` is `timeout()`, so there is no need to have the flexibility to pass a different error message * use `wraps()` as a decorator, simpler this way. Signed-off-by: Kefu Chai --- .../diskprediction_cloud/agent/__init__.py | 4 +-- .../diskprediction_cloud/common/__init__.py | 32 +++++++++---------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/pybind/mgr/diskprediction_cloud/agent/__init__.py b/src/pybind/mgr/diskprediction_cloud/agent/__init__.py index c7702e5242c..e7e0ddcb6ed 100644 --- a/src/pybind/mgr/diskprediction_cloud/agent/__init__.py +++ b/src/pybind/mgr/diskprediction_cloud/agent/__init__.py @@ -29,10 +29,10 @@ class BaseAgent(object): else: return True - @timeout() + @timeout def _run(self): pass - @timeout() + @timeout def _collect_data(self): pass diff --git a/src/pybind/mgr/diskprediction_cloud/common/__init__.py b/src/pybind/mgr/diskprediction_cloud/common/__init__.py index ce5131b8f2b..be409416639 100644 --- a/src/pybind/mgr/diskprediction_cloud/common/__init__.py +++ b/src/pybind/mgr/diskprediction_cloud/common/__init__.py @@ -26,28 +26,26 @@ class DummyResonse: class TimeoutError(Exception): - pass + def __init__(self): + super(TimeoutError, self).__init__("Timer expired") -def timeout(seconds=10, error_message=os.strerror(errno.ETIME)): - def decorator(func): - def _handle_timeout(signum, frame): - raise TimeoutError(error_message) +def timeout(func): + DEFAULT_TIMEOUT = 10 - def wrapper(*args, **kwargs): - if hasattr(args[0], '_timeout') is not None: - seconds = args[0]._timeout - signal.signal(signal.SIGALRM, _handle_timeout) - signal.alarm(seconds) - try: - result = func(*args, **kwargs) - finally: - signal.alarm(0) - return result + def _handle_timeout(signum, frame): + raise TimeoutError() - return wraps(func)(wrapper) + @wraps(func) + def wrapper(self): + signal.signal(signal.SIGALRM, _handle_timeout) + signal.alarm(getattr(self, '_timeout', DEFAULT_TIMEOUT)) + try: + return func(self) + finally: + signal.alarm(0) - return decorator + return wrapper def get_human_readable(size, precision=2): -- 2.47.3