blob: 6401990adb72fbb96ab7b63f70c38a6b664f0bf6 [file] [log] [blame]
Chris Masone6f109082012-07-18 14:21:38 -07001# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
Alex Miller320dac92013-01-09 21:18:13 -08005import logging, random, time
Chris Masone6f109082012-07-18 14:21:38 -07006from autotest_lib.client.common_lib import error
7from autotest_lib.frontend.afe.json_rpc import proxy
8
9
Alex Miller320dac92013-01-09 21:18:13 -080010def retry(ExceptionToCheck, timeout_min=1, delay_sec=3):
Chris Masone6f109082012-07-18 14:21:38 -070011 """Retry calling the decorated function using a delay with jitter.
12
13 Will raise RPC ValidationError exceptions from the decorated
14 function without retrying; a malformed RPC isn't going to
15 magically become good.
16
17 original from:
18 http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
19
20 @param ExceptionToCheck: the exception to check. May be a tuple of
21 exceptions to check.
22 @param timeout_min: timeout in minutes until giving up.
23 @param delay_sec: pre-jittered delay between retries in seconds. Actual
24 delays will be centered around this value, ranging up to
25 50% off this midpoint.
26 """
27 def deco_retry(func):
28 random.seed()
29 def func_retry(*args, **kwargs):
30 deadline = time.time() + timeout_min * 60 # convert to seconds.
31 while time.time() < deadline:
32 try:
Alex Miller320dac92013-01-09 21:18:13 -080033 return func(*args, **kwargs)
34 except error.CrosDynamicSuiteException, e:
35 raise e
36 except proxy.ValidationError, e:
37 raise e
38 except ExceptionToCheck, e:
39 # 'Jitter' the delay, up to 50% in either direction.
40 delay = random.uniform(.5 * delay_sec, 1.5 * delay_sec)
41 logging.warning("%s(%s), Retrying in %f seconds...",
42 e.__class__, e, delay)
43 time.sleep(delay)
Chris Masone6f109082012-07-18 14:21:38 -070044 else:
Alex Miller320dac92013-01-09 21:18:13 -080045 # On the last try, run func() and allow exceptions to escape.
46 return func(*args, **kwargs)
47 return
Chris Masone6f109082012-07-18 14:21:38 -070048 return func_retry # true decorator
49 return deco_retry