import time import redis import traceback from functools import wraps def redis_exception_handler(func): def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except redis.exceptions.ResponseError as error: from app import app app.logger.error("Redis Error: ", f"{error}\n{traceback.format_exc()}") return None return wrapper def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None): """Retry calling the decorated function using an exponential backoff. http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/ original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry :param ExceptionToCheck: the exception to check. may be a tuple of exceptions to check :type ExceptionToCheck: Exception or tuple :param tries: number of times to try (not retry) before giving up :type tries: int :param delay: initial delay between retries in seconds :type delay: int :param backoff: backoff multiplier e.g. value of 2 will double the delay each retry :type backoff: int :param logger: logger to use. If None, print :type logger: logging.Logger instance """ def deco_retry(f): @wraps(f) def f_retry(*args, **kwargs): mtries, mdelay = tries, delay while mtries > 1: try: return f(*args, **kwargs) except ExceptionToCheck as e: msg = "%s, Retrying in %d seconds..." % (str(e), mdelay) if logger: logger.warning(msg) else: print(msg) time.sleep(mdelay) mtries -= 1 mdelay *= backoff return f(*args, **kwargs) return f_retry return deco_retry def timeit(method): def timed(*args, **kw): ts = time.time() result = method(*args, **kw) te = time.time() if "log_time" in kw: name = kw.get("log_name", method.__name__.upper()) kw["log_time"][name] = int((te - ts) * 1000) else: print("%r %1.4f s" % (method.__name__, (te - ts))) return result return timed