Ejemplo n.º 1
0
    def __init__(self, registry: Dict[str, HA]):
        self.registry = registry

        self.lastcheck = {}  # type: Dict[int, Tuple[int, float]]
        self.ratchet = Ratchet(a=8, b=0.198, c=-4, base=8, peak=3600)

        # holds the last time we checked remotes
        self.nextCheck = 0
Ejemplo n.º 2
0
async def eventually(coroFunc: FlexFunc,
                     *args,
                     retryWait: float = 0.1,
                     timeout: float = 5,
                     ratchetSteps: Optional[int] = None,
                     acceptableExceptions=None,
                     verbose=True) -> T:

    if acceptableExceptions and not isinstance(acceptableExceptions, Iterable):
        acceptableExceptions = [acceptableExceptions]
    start = time.perf_counter()

    ratchet = Ratchet.fromGoalDuration(retryWait*slowFactor,
                                       ratchetSteps,
                                       timeout*slowFactor).gen() \
        if ratchetSteps else None

    fname = getFuncName(coroFunc)
    while True:
        remain = 0
        try:
            remain = start + timeout * slowFactor - time.perf_counter()
            if remain < 0:
                # this provides a convenient breakpoint for a debugger
                logger.warning("{} last try...".format(fname),
                               extra={"cli": False})
            # noinspection PyCallingNonCallable
            res = coroFunc(*args)

            if isawaitable(res):
                result = await res
            else:
                result = res

            if verbose:
                recordSuccess(fname, timeout, timeout * slowFactor, remain)

                logger.debug(
                    "{} succeeded with {:.2f} seconds to spare".format(
                        fname, remain))
            return result
        except Exception as ex:
            if acceptableExceptions and type(ex) not in acceptableExceptions:
                raise
            if remain >= 0:
                if verbose:
                    logger.trace("{} not succeeded yet, {:.2f} seconds "
                                 "remaining...".format(fname, remain))
                await asyncio.sleep(next(ratchet) if ratchet else retryWait)
            else:
                recordFail(fname, timeout)
                logger.error("{} failed; not trying any more because {} "
                             "seconds have passed; args were {}".format(
                                 fname, timeout, args))
                raise ex
Ejemplo n.º 3
0
def test_throttler_case2():
    """
    Tests throttler with custom delay function
    """
    windowSize = 10
    testIterations = windowSize - 2
    ratchet = Ratchet(a=2, b=0.05, c=1, base=2, peak=windowSize)
    throttler = Throttler(windowSize, ratchet.get)
    cooldowns = [
        time.sleep(1) or throttler.acquire()[1] for i in range(testIterations)
    ]
    middle = len(cooldowns) // 2
    firstIteration, secondIteration = cooldowns[:middle], cooldowns[middle:]
    for a, b in zip(firstIteration, secondIteration):
        if not a == b == 0:
            assert b > a
Ejemplo n.º 4
0
 def initInsChngThrottling(self):
     windowSize = self.node.config.ViewChangeWindowSize
     ratchet = Ratchet(a=2, b=0.05, c=1, base=2, peak=windowSize)
     self.insChngThrottler = Throttler(windowSize, ratchet.get)
Ejemplo n.º 5
0
async def eventually(coroFunc: FlexFunc,
                     *args,
                     retryWait: float=0.1,
                     timeout: float=5,
                     ratchetSteps: Optional[int]=None,
                     acceptableExceptions=None,
                     verbose=True,
                     override_timeout_limit=False) -> T:
    assert timeout > 0, 'Need a timeout value of greater than 0 but got {} instead'.format(timeout)
    if not override_timeout_limit:
        assert timeout < 240, '`eventually` timeout ({:.2f} sec) is huge. ' \
                                 'Is it expected?'.format(timeout)
    else:
        logger.debug('Overriding timeout limit to {} for evaluating {}'
                     .format(timeout, coroFunc))
    if acceptableExceptions and not isinstance(acceptableExceptions, Iterable):
            acceptableExceptions = [acceptableExceptions]
    start = time.perf_counter()

    ratchet = Ratchet.fromGoalDuration(retryWait*slowFactor,
                                       ratchetSteps,
                                       timeout*slowFactor).gen() \
        if ratchetSteps else None

    fname = getFuncName(coroFunc)
    while True:
        remain = 0
        try:
            remain = start + timeout*slowFactor - time.perf_counter()
            if remain < 0:
                # this provides a convenient breakpoint for a debugger
                logger.warning("{} last try...".format(fname),
                               extra={"cli": False})
            # noinspection PyCallingNonCallable
            res = coroFunc(*args)

            if isawaitable(res):
                result = await res
            else:
                result = res

            if verbose:
                recordSuccess(fname, timeout, timeout*slowFactor, remain)

                logger.debug("{} succeeded with {:.2f} seconds to spare".
                             format(fname, remain))
            return result
        except Exception as ex:
            if acceptableExceptions and type(ex) not in acceptableExceptions:
                raise
            if remain >= 0:
                sleep_dur = next(ratchet) if ratchet else retryWait
                if verbose:
                    logger.trace("{} not succeeded yet, {:.2f} seconds "
                                 "remaining..., will sleep for {}".format(fname, remain, sleep_dur))
                await asyncio.sleep(sleep_dur)
            else:
                recordFail(fname, timeout)
                logger.error("{} failed; not trying any more because {} "
                             "seconds have passed; args were {}".
                             format(fname, timeout, args))
                raise ex
Ejemplo n.º 6
0
async def eventually(coroFunc: FlexFunc,
                     *args,
                     retryWait: float=0.1,
                     timeout: float=5,
                     ratchetSteps: Optional[int]=None,
                     acceptableExceptions=None,
                     verbose=True,
                     override_timeout_limit=False) -> T:
    if not timeout > 0:
        raise PlenumValueError('timeout', timeout, '> 0')
    if not override_timeout_limit:
        if timeout > 240:
            raise PlenumValueError(
                'timeout', timeout,
                "< 240 or override_timeout_limit=True"
            )
    else:
        logger.debug('Overriding timeout limit to {} for evaluating {}'
                     .format(timeout, coroFunc))
    if acceptableExceptions and not isinstance(acceptableExceptions, Iterable):
        acceptableExceptions = [acceptableExceptions]
    start = time.perf_counter()

    ratchet = Ratchet.fromGoalDuration(retryWait * slowFactor,
                                       ratchetSteps,
                                       timeout * slowFactor).gen() \
        if ratchetSteps else None

    fname = get_func_name(coroFunc)
    while True:
        remain = 0
        try:
            remain = start + timeout * slowFactor - time.perf_counter()
            if remain < 0:
                # this provides a convenient breakpoint for a debugger
                logger.debug("{} last try...".format(fname),
                             extra={"cli": False})
            # noinspection PyCallingNonCallable
            res = coroFunc(*args)

            if isawaitable(res):
                result = await res
            else:
                result = res

            if verbose:
                recordSuccess(fname, timeout, timeout * slowFactor, remain)

                logger.debug("{} succeeded with {:.2f} seconds to spare".
                             format(fname, remain))
            return result
        except Exception as ex:
            if acceptableExceptions and type(ex) not in acceptableExceptions:
                raise
            if remain >= 0:
                sleep_dur = next(ratchet) if ratchet else retryWait
                if verbose:
                    logger.trace("{} not succeeded yet, {:.2f} seconds "
                                 "remaining..., will sleep for {}".format(fname, remain, sleep_dur))
                await asyncio.sleep(sleep_dur)
            else:
                recordFail(fname, timeout)
                logger.error("{} failed; not trying any more because {} "
                             "seconds have passed; args were {}".
                             format(fname, timeout, args))
                raise ex