def retry_until_ok(func, *args, **kwargs):
    """Retry code block until it succeeds.

    If it does not succeed in 120 attempts, the function re-raises any
    error the function raised on its last attempt.

    """
    max_tries = 120
    for i in range(max_tries):
        try:
            return func(*args, **kwargs)
        except RuntimeError:
            # Do not mask RuntimeError.
            raise
        except errors.OperationFailure as exc:
            if exc.code == 13 or (  # MongoDB >= 2.6 sets the error code,
                exc.details
                and "unauthorized" == exc.details.get("errmsg")  # MongoDB 2.4 does not.
            ):
                # Do not mask authorization failures.
                raise
            if i == max_tries - 1:
                LOG.exception(
                    "Call to %s failed too many times in " "retry_until_ok", func
                )
                raise
        except Exception:
            if i == max_tries - 1:
                LOG.exception(
                    "Call to %s failed too many times in " "retry_until_ok", func
                )
                raise
        time.sleep(1)
def retry_until_ok ( func , * args , ** kwargs ) : max_tries = 120 for i in range ( max_tries ) : try : return func ( * args , ** kwargs ) except RuntimeError : raise except errors . OperationFailure as exc : if exc . code == 13 or ( exc . details and "unauthorized" == exc . details . get ( "errmsg" ) ) : raise if i == max_tries - 1 : LOG . exception ( "Call to %s failed too many times in " "retry_until_ok" , func ) raise except Exception : if i == max_tries - 1 : LOG . exception ( "Call to %s failed too many times in " "retry_until_ok" , func ) raise time . sleep ( 1 )
Retry code block until it succeeds.

    If it does not succeed in 120 attempts, the function re-raises any
    error the function raised on its last attempt.