docs: def retry(f, exc_classes=DEFAULT_EXC_CLASSES, logger=None,
            retry_log_level=logging.INFO,
            retry_log_message="Connection broken in '{f}' (error: '{e}'); "
                              "retrying with new connection.",
            max_failures=None, interval=0,
            max_failure_log_level=logging.ERROR,
            max_failure_log_message="Max retries reached for '{f}'. Aborting."):
      """
      Decorator to automatically reexecute a function if the connection is
      broken for any reason.
      """
      exc_classes = tuple(exc_classes)
  
      @wraps(f)
      def deco(*args, **kwargs):
          failures = 0
          while True:
              try:
                  return f(*args, **kwargs)
              except exc_classes as e:
                  if logger is not None:
                      logger.log(retry_log_level,
                                 retry_log_message.format(f=f.func_name, e=e))
                  gevent.sleep(interval)
                  failures += 1
                  if max_failures is not None \
                          and failures > max_failures:
                      if logger is not None:
                          logger.log(max_failure_log_level,
                                     max_failure_log_message.format(
                                         f=f.func_name, e=e))
                      raise
      return deco