def __call__(self, obj, *args, **kwargs):
        """
        Attempts the function call, catching exception, re-connecting, and retrying, up to a
        pre-configured maximum number of attempts.

        :param obj: calling class instance, the HDFS client object
        :param args: positional arguments to func
        :param kwargs: arbitrary keyword arguments to func
        :return: return of ``func`` call; if max retries exceeded, raise a RuntimeError; or raise
                any unexpected exception
        """
        failures = []
        while len(failures) <= self.MAX_FAILOVER_ATTEMPTS:
            try:
                # Invoke the filesystem function on the connected HDFS object
                return getattr(obj._hdfs, self._func_name)(*args, **kwargs)
            except ArrowIOError as e:
                # An HDFS IP error occurred, retry HDFS connect to failover
                obj._do_connect()
                failures.append(e)
        # Failover attempts exceeded at this point!
        raise MaxFailoversExceeded(failures, self.MAX_FAILOVER_ATTEMPTS, self._func_name)

        Attempts the function call, catching exception, re-connecting, and retrying, up to a
        pre-configured maximum number of attempts.

        :param obj: calling class instance, the HDFS client object
        :param args: positional arguments to func
        :param kwargs: arbitrary keyword arguments to func
        :return: return of ``func`` call; if max retries exceeded, raise a RuntimeError; or raise
                any unexpected exception
        
petastorm/hdfs/namenode.py