code: def _deadline_until(cls, closure, action_msg, timeout=FAIL_WAIT_SEC,
                        wait_interval=WAIT_INTERVAL_SEC, info_interval=INFO_INTERVAL_SEC):
      
      now = time.time()
      deadline = now + timeout
      info_deadline = now + info_interval
      while 1:
        if closure():
          return True
  
        now = time.time()
        if now > deadline:
          raise cls.Timeout('exceeded timeout of {} seconds while waiting for {}'.format(timeout, action_msg))
  
        if now > info_deadline:
          logger.info('waiting for {}...'.format(action_msg))
          info_deadline = info_deadline + info_interval
        elif wait_interval:
          time.sleep(wait_interval)
docs: Execute a function/closure repeatedly until a True condition or timeout is met.
  
      :param func closure: the function/closure to execute (should not block for long periods of time
                           and must return True on success).
      :param str action_msg: a description of the action that is being executed, to be rendered as
                             info while we wait, and as part of any rendered exception.
      :param float timeout: the maximum amount of time to wait for a true result from the closure in
                            seconds. N.B. this is timing based, so won't be exact if the runtime of
                            the closure exceeds the timeout.
      :param float wait_interval: the amount of time to sleep between closure invocations.
      :param float info_interval: the amount of time to wait before and between reports via info
                                  logging that we're still waiting for the closure to succeed.
      :raises: :class:`ProcessManager.Timeout` on execution timeout.