ok

Mini Shell

Direktori : /var/opt/nydus/ops/customer_local_ops/util/
Upload File :
Current File : //var/opt/nydus/ops/customer_local_ops/util/retry.py

# -*- coding: utf-8 -*-

"""\
© Copyright. All rights reserved.

"""

from __future__ import unicode_literals
from datetime import datetime, timedelta
from functools import wraps
import logging

LOG = logging.getLogger(__name__)


class Retry:
    """Ops decorated with @retry can return a Retry instance to request retry
    with the interval and timeout as specified in the decorator.  See also the
    RETRY sentinel if there is no intermediate_result.
    """

    def __init__(self, intermediate_result=None):
        if not (intermediate_result is None or
                isinstance(intermediate_result, dict)):
            raise TypeError('Retry intermediate_result must be dictionary '
                            'but got %s' % type(intermediate_result))
        self.intermediate_result = intermediate_result

    def __str__(self):
        return 'Retry ' + str(self.__dict__)


RETRY = Retry()  # A Retry that can be returned from ops decorated with @retry
# when there is no intermediate_result.


def retry(interval=2, timeout=60):
    """Op decorator that returns a retry request to Nydus when the op returns
    a Retry instance.  Op will be retried by Nydus after `interval` seconds.
    Returns failure at the specified timeout (seconds).
    """

    def deco(original):
        @wraps(original)
        def wrapper(*args, **kw):
            intermediate_result = kw.get('intermediate_result', None)

            now = datetime.utcnow()
            timeout_abs = (intermediate_result and
                           intermediate_result.get('timeout') or
                           now + timedelta(seconds=timeout))

            if now >= timeout_abs:
                msg = 'Timeout waiting for {} ({}s)'.format(getattr(original, '__name__', '?'), timeout)
                LOG.error(msg)
                return False, msg

            result = original(*args, **kw)

            if isinstance(result, Retry):
                ir = result.intermediate_result or {}
                ir.setdefault('timeout', timeout_abs)
                return False, ir, interval
            return result

        return wrapper
    return deco

Zerion Mini Shell 1.0