def RetryOnFailure()

in daisy_workflows/linux_common/utils/common.py [0:0]


def RetryOnFailure(stop_after_seconds=15 * 60, initial_delay_seconds=3):
  """Function decorator to retry on an exception.

  Performs linear backoff until stop_after_seconds is reached.

  Args:
    stop_after_seconds: Maximum amount of time (in seconds) to spend retrying.
    initial_delay_seconds: The delay before the first retry, in seconds."""
  def decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
      ratio = 1.5
      wait = initial_delay_seconds
      ntries = 0
      start_time = time.time()
      # Stop after five minutes.
      end_time = start_time + stop_after_seconds
      exception = None
      while time.time() < end_time:
        # Don't sleep on first attempt.
        if ntries > 0:
          time.sleep(wait)
          wait *= ratio
        ntries += 1
        try:
          response = func(*args, **kwargs)
        except Exception as e:
          exception = e
          logging.info(str(e))
          logging.info(
              'Function %s failed, waiting %d seconds, retrying %d ...',
              str(func), wait, ntries)
        else:
          logging.info(
              'Function %s executed in less then %d sec, with %d tentative(s)',
              str(func), time.time() - start_time, ntries)
          return response
      raise exception
    return wrapper
  return decorator