3
# Copyright (C) 2015 Canonical
5
# This program is free software: you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation, either version 3 of the License, or
8
# (at your option) any later version.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with this program. If not, see <http://www.gnu.org/licenses/>.
25
logger = logging.getLogger('PractiSanity')
26
logger.setLevel(logging.INFO)
27
stdout_handler = logging.StreamHandler(sys.stdout)
28
stdout_handler.setLevel(logging.DEBUG)
29
logger.addHandler(stdout_handler)
32
def retry(ExceptionToCheck, tries=4, delay=2, backoff=2, logger=None):
33
"""Retry calling the decorated function using an exponential backoff.
35
http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
36
Original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
38
:param ExceptionToCheck: the exception to check. may be a tuple of
40
:param tries: number of times to try (not retry) before giving up
41
:param delay: initial delay between retries in seconds
42
:param backoff: backoff multiplier e.g. value of 2 will double the delay
44
:param logger: logger.Logger to use.
49
def f_retry(*args, **kwargs):
50
for i in range(tries):
52
return f(*args, **kwargs)
53
except ExceptionToCheck as e:
54
d = delay * backoff ** i
57
"%s, retrying in %d seconds. . . ." % (e, d))
59
return f(*args, **kwargs)
60
return f_retry # true decorator
67
results.append(q.get())