~stephanpampel/landscape-charm/landscape-monitoring

« back to all changes in this revision

Viewing changes to charmhelpers/core/decorators.py

  • Committer: Stephan Pampel
  • Date: 2021-10-28 09:41:30 UTC
  • Revision ID: stephan.pampel@canonical.com-20211028094130-to14fxkpxvrqnh2k
Add charmhelpers.contrib.charmsupport dependency to charm-helpers.yaml to get nrpe.py
Sync charm-helpers

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
        return _retry_on_exception_inner_2
54
54
 
55
55
    return _retry_on_exception_inner_1
 
56
 
 
57
 
 
58
def retry_on_predicate(num_retries, predicate_fun, base_delay=0):
 
59
    """Retry based on return value
 
60
 
 
61
    The return value of the decorated function is passed to the given predicate_fun. If the
 
62
    result of the predicate is False, retry the decorated function up to num_retries times
 
63
 
 
64
    An exponential backoff up to base_delay^num_retries seconds can be introduced by setting
 
65
    base_delay to a nonzero value. The default is to run with a zero (i.e. no) delay
 
66
 
 
67
    :param num_retries: Max. number of retries to perform
 
68
    :type num_retries: int
 
69
    :param predicate_fun: Predicate function to determine if a retry is necessary
 
70
    :type predicate_fun: callable
 
71
    :param base_delay: Starting value in seconds for exponential delay, defaults to 0 (no delay)
 
72
    :type base_delay: float
 
73
    """
 
74
    def _retry_on_pred_inner_1(f):
 
75
        def _retry_on_pred_inner_2(*args, **kwargs):
 
76
            retries = num_retries
 
77
            multiplier = 1
 
78
            delay = base_delay
 
79
            while True:
 
80
                result = f(*args, **kwargs)
 
81
                if predicate_fun(result) or retries <= 0:
 
82
                    return result
 
83
                delay *= multiplier
 
84
                multiplier += 1
 
85
                log("Result {}, retrying '{}' {} more times (delay={})".format(
 
86
                    result, f.__name__, retries, delay), level=INFO)
 
87
                retries -= 1
 
88
                if delay:
 
89
                    time.sleep(delay)
 
90
 
 
91
        return _retry_on_pred_inner_2
 
92
 
 
93
    return _retry_on_pred_inner_1