def consul(run_container, run_id): """runs Consul in Docker and returns ConsulClient""" container = run_container( "consul:1.5.3", 8500, command="consul agent -dev -client 0.0.0.0", name=f"{run_id}_consul", hostname="consul", ) # wait for Consul to start bag = ConsulBag(container=container) retry(20, RequestException, 0.1)(lambda: bag.client.kv.get("1"))() return bag
def _gdrive_retry(func): def should_retry(exc): from pydrive2.files import ApiRequestError if not isinstance(exc, ApiRequestError): return False error_code = exc.error.get("code", 0) result = False if 500 <= error_code < 600: result = True if error_code == 403: result = exc.GetField("reason") in [ "userRateLimitExceeded", "rateLimitExceeded", ] if result: logger.debug(f"Retrying GDrive API call, error: {exc}.") return result # 16 tries, start at 0.5s, multiply by golden ratio, cap at 20s return retry( 16, timeout=lambda a: min(0.5 * 1.618 ** a, 20), filter_errors=should_retry, )(func)
def _remove(path): if os.name == "nt": # git.exe may hang for a while not permitting to remove temp dir os_retry = retry(5, errors=OSError, timeout=0.1) os_retry(remove)(path) else: remove(path)
def _should_retry(func): api_request_limit_errors = ['userRateLimitExceeded', 'rateLimitExceeded'] def should_retry(exc): if not isinstance(exc, ApiRequestError): return False error_code = exc.error.get('code', 0) result = False if INTERNAL_SERVER_ERROR <= error_code < INTERNAL_SERVER_ERROR + 100: result = True if error_code == FORBIDDEN: result = exc.GetField('reason') in api_request_limit_errors if result: log.debug(f'Google Drive API error: {exc}.', class_name=GDRIVE_STORAGE) return result start, ratio, limit = 0.5, 1.618, 20 return retry( 16, timeout=lambda a: min(start * ratio**a, limit), filter_errors=should_retry, )(func)
def _gdrive_retry(func): def should_retry(exc): from googleapiclient.errors import HttpError if not isinstance(exc, HttpError): return False if 500 <= exc.resp.status < 600: return True if exc.resp.status == 403: try: reason = json.loads(exc.content)["error"]["errors"][0][ "reason" ] except (ValueError, LookupError): return False return reason in [ "userRateLimitExceeded", "rateLimitExceeded", ] # 16 tries, start at 0.5s, multiply by golden ratio, cap at 20s return retry( 16, timeout=lambda a: min(0.5 * 1.618 ** a, 20), filter_errors=should_retry, )(func)
def _remove(repo): repo.scm.close() if os.name == "nt": # git.exe may hang for a while not permitting to remove temp dir os_retry = retry(5, errors=OSError, timeout=0.1) os_retry(remove)(repo.root_dir) else: remove(repo.root_dir)
def _git_init(path): from git import Repo from git.exc import GitCommandNotFound # NOTE: handles EAGAIN error on BSD systems (osx in our case). # Otherwise when running tests you might get this exception: # # GitCommandNotFound: Cmd('git') not found due to: # OSError('[Errno 35] Resource temporarily unavailable') git = retry(5, GitCommandNotFound)(Repo.init)(path) git.close()
def _remove(path): if os.name == "nt": # git.exe may hang for a while not permitting to remove temp dir os_retry = retry(5, errors=OSError, timeout=0.1) try: os_retry(remove)(path) except PermissionError: logger.warning("Failed to remove '%s'", relpath(path), exc_info=True) else: remove(path)
def gdrive_retry(func): from pydrive2.files import ApiRequestError retry_re = re.compile(r"HttpError (403|500|502|503|504)") # 15 tries, start at 0.5s, multiply by golden ratio, cap at 20s return retry( 15, timeout=lambda a: min(0.5 * 1.618**a, 20), errors=ApiRequestError, filter_errors=lambda exc: retry_re.search(str(exc)), )(func)
def gdrive_retry(func): def should_retry(exc): from pydrive2.files import ApiRequestError if not isinstance(exc, ApiRequestError): return False retry_codes = [403, 500, 502, 503, 504] return exc.error.get("code", 0) in retry_codes # 15 tries, start at 0.5s, multiply by golden ratio, cap at 20s return retry( 15, timeout=lambda a: min(0.5 * 1.618**a, 20), filter_errors=should_retry, )(func)
def uninstall(self): if not self.installed: logger.info( "Skipping uninstalling '{}' as it is not installed.".format( self.name)) return # If repo has been initialized then we need to close its git repo if "repo" in self.__dict__: self.repo.scm.git.close() if os.name == "nt": # git.exe may hang for a while not permitting to remove temp dir os_retry = retry(5, errors=OSError, timeout=0.1) os_retry(remove)(self.path) else: remove(self.path)
def gdrive_retry(func, retries=15): def should_retry(exc): from pydrive2.files import ApiRequestError if isinstance(exc, ApiRequestError): if isinstance(exc.exception(), HttpError): status = exc.exception().resp.status return (403 == status or 500 == status or 502 == status or 503 == status or 504 == status) else: return False # 15 tries, start at 0.5s, multiply by golden ratio, cap at 20s return retry( tries=retries, timeout=lambda a: min(0.5 * 1.618**a, 20), filter_errors=should_retry, )(func)
def gdrive_retry(func): def should_retry(exc): from pydrive2.files import ApiRequestError if not isinstance(exc, ApiRequestError): return False retry_codes = [403, 500, 502, 503, 504] result = exc.error.get("code", 0) in retry_codes if result: logger.debug("Retry GDrive API call failed with {}.".format(exc)) return result # 15 tries, start at 0.5s, multiply by golden ratio, cap at 20s return retry( 15, timeout=lambda a: min(0.5 * 1.618**a, 20), filter_errors=should_retry, )(func)
def _dropbox_retry(func): def should_retry(exc): import dropbox if not isinstance( exc, ( dropbox.exceptions.InternalServerError, dropbox.exceptions.RateLimitError, ), ): return False logger.debug(f"Retrying Dropbox API call, error: {exc}.") return True # 16 tries, start at 0.5s, multiply by golden ratio, cap at 20s return retry( 16, timeout=lambda a: min(0.5 * 1.618 ** a, 20), filter_errors=should_retry, )(func)
def lock(self): retries = 6 delay = DEFAULT_TIMEOUT / retries lock_retry = retry(retries, LockError, timeout=delay)(self._do_lock) lock_retry()
def _timeout(i): from app import app if app.config.get('TESTING'): return 0 return 2 ** i def wait(wait_range=15): wait_time = random.choice(range(wait_range)) logger.info('Wait %s seconds.', wait_time) time.sleep(wait_time) requests_retry = retry(RETRY_COUNT, errors=requests.RequestException, timeout=_timeout) class IntercomError(Exception): """ Base exception for IntercomClient. """ class IntercomValidationError(IntercomError): """ Incorrect value for one of the request's parameter. """ class IntercomClient: """ Client for making requests to the Intercom's API. Ref: https://developers.intercom.io/docs
def wait_for_t_role(t, mode, seconds, autovshard_docker_cluster): check = retry(seconds, errors=(AssertionError, APIError), timeout=1)(do_check_t_actual_role, ) check(t, mode, autovshard_docker_cluster)
from pydrive2.files import ApiRequestError try: result = call() except ApiRequestError as exception: retry_codes = ["403", "500", "502", "503", "504"] if any("HttpError {}".format(code) in str(exception) for code in retry_codes): raise GDriveRetriableError("Google API request failed") raise return result gdrive_retry = compose( # 15 tries, start at 0.5s, multiply by golden ratio, cap at 20s retry(15, GDriveRetriableError, timeout=lambda a: min(0.5 * 1.618**a, 20)), _wrap_pydrive_retriable, ) class GDriveURLInfo(CloudURLInfo): def __init__(self, url): super().__init__(url) # GDrive URL host part is case sensitive, # we are restoring it here. p = urlparse(url) self.host = p.netloc assert self.netloc == self.host # Normalize path. Important since we have a cache (path to ID)