commit:     6d822cbc2a7a68e39583991b3f69ff76b032d585
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Mon Mar 19 07:37:38 2018 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Apr  2 16:53:23 2018 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=6d822cbc

Add ExponentialBackoff and RandomExponentialBackoff

This will be useful as parameters for retry decorators.

 pym/portage/util/backoff.py | 53 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/pym/portage/util/backoff.py b/pym/portage/util/backoff.py
new file mode 100644
index 000000000..ee39007ef
--- /dev/null
+++ b/pym/portage/util/backoff.py
@@ -0,0 +1,53 @@
+# Copyright 2018 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+__all__ = (
+       'ExponentialBackoff',
+       'RandomExponentialBackoff',
+)
+
+import random
+import sys
+
+
+class ExponentialBackoff(object):
+       """
+       An object that when called with number of previous tries, calculates
+       an exponential delay for the next try.
+       """
+       def __init__(self, multiplier=1, base=2, limit=sys.maxsize):
+               """
+               @param multiplier: constant multiplier
+               @type multiplier: int or float
+               @param base: maximum number of tries
+               @type base: int or float
+               @param limit: maximum number of seconds to delay
+               @type limit: int or float
+               """
+               self._multiplier = multiplier
+               self._base = base
+               self._limit = limit
+
+       def __call__(self, tries):
+               """
+               Given a number of previous tries, calculate the amount of time
+               to delay the next try.
+
+               @param tries: number of previous tries
+               @type tries: int
+               @return: amount of time to delay the next try
+               @rtype: int
+               """
+               try:
+                       return min(self._limit, self._multiplier * (self._base 
** tries))
+               except OverflowError:
+                       return self._limit
+
+
+class RandomExponentialBackoff(ExponentialBackoff):
+       """
+       Equivalent to ExponentialBackoff, with an extra multiplier that uses
+       a random distribution between 0 and 1.
+       """
+       def __call__(self, tries):
+               return random.random() * super(RandomExponentialBackoff, 
self).__call__(tries)

Reply via email to