def reconnecting(count=None, backoff=None):
<EOL>reconn_params = {<EOL>"<STR_LIT:count>": count,<EOL>"<STR_LIT>": backoff<EOL>}<EOL>def retry_decorator(func):<EOL><INDENT>@wraps(func)<EOL>def wrapper(self, *args, **kwargs):<EOL><INDENT>count = reconn_params["<STR_LIT:count>"]<EOL>backoff = reconn_params["<STR_LIT>"]<EOL>if count is None:<EOL><INDENT>count = self.connection_config.options.get('<STR_LIT>', <NUM_LIT:3>)<EOL><DEDENT>if backoff is None:<EOL><INDENT>backoff = self.connection_config.options.get('<STR_LIT>', <NUM_LIT:1.0>)<EOL><DEDENT>count = int(count)<EOL>backoff = float(backoff)<EOL>for attempt in range(<NUM_LIT:1>, count + <NUM_LIT:1>):<EOL><INDENT>try:<EOL><INDENT>backoff_seconds = float(attempt - <NUM_LIT:1>) * backoff<EOL>if backoff_seconds:<EOL><INDENT>logger.debug("<STR_LIT>".format(<EOL>backoff_seconds,<EOL>attempt<EOL>))<EOL><DEDENT>time.sleep(backoff_seconds)<EOL>return func(self, *args, **kwargs)<EOL><DEDENT>except InterfaceError as e:<EOL><INDENT>e_msg = str(e.e)<EOL>if "<STR_LIT>" in e_msg.lower():<EOL><INDENT>if attempt == count:<EOL><INDENT>logger.debug("<STR_LIT>".format(count))<EOL>raise<EOL><DEDENT>else:<EOL><INDENT>logger.debug("<STR_LIT>".format(<EOL>attempt,<EOL>count<EOL>))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return wrapper<EOL><DEDENT>return retry_decorator<EOL>
this is a very specific decorator meant to be used on Interface classes.
    It will attempt to reconnect if the connection is closed and run the same 
    method again.

    TODO -- I think this will have issues with transactions using passed in
    connections, ie, you pass in a transacting connection to the insert() method
    and that connection gets dropped, this will reconnect but the transaction will
    be hosed.

    count -- integer -- how many attempts to run the method, defaults to 3
    backoff -- float -- how long to sleep on failure, defaults to 1.0