aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Górny <mgorny@gentoo.org>2018-07-17 21:50:45 +0200
committerZac Medico <zmedico@gentoo.org>2018-07-18 16:19:11 -0700
commitbc0fa8d3795ed7e40aaa00f579bb2977897bce25 (patch)
tree2a62c721ee8dec47ddb564254e1cbd967577d1f0 /lib/portage/util/backoff.py
parentEventLoop: raise TypeError for unexpected call_* keyword args (diff)
downloadportage-bc0fa8d3795ed7e40aaa00f579bb2977897bce25.tar.gz
portage-bc0fa8d3795ed7e40aaa00f579bb2977897bce25.tar.bz2
portage-bc0fa8d3795ed7e40aaa00f579bb2977897bce25.zip
Rename pym→lib, for better distutils-r1 interoperability
Closes: https://github.com/gentoo/portage/pull/343
Diffstat (limited to 'lib/portage/util/backoff.py')
-rw-r--r--lib/portage/util/backoff.py53
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/portage/util/backoff.py b/lib/portage/util/backoff.py
new file mode 100644
index 000000000..ee39007ef
--- /dev/null
+++ b/lib/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)