'Retry the request a few times before we determine it failed.
Sometimes the frontend becomes loaded and issues a 500 error to throttle the
clients. We wait Client.error_poll_min seconds between each attempt to back
off the frontend. Note that this does not affect any timing algorithm in the
client itself which is controlled by the Timer() class.
Args:
timeout: Timeout for retry.
**request_args: Args to the requests.request call.
Returns:
a tuple of duration, urllib2.urlopen response.'

def _RetryRequest(self, timeout=None, **request_args):

    while True:
        try:
            now = time.time()
            if (not timeout):
                timeout = config.CONFIG['Client.http_timeout']
            result = requests.request(**request_args)
            result.raise_for_status()
            if (not result.ok):
                raise requests.RequestException(response=result)
            return ((time.time() - now), result)
        except IOError as e:
            self.consecutive_connection_errors += 1
            if (self.active_base_url is not None):
                response = getattr(e, 'response', None)
                if (getattr(response, 'status_code', None) == 406):
                    raise
                if (self.consecutive_connection_errors >= self.retry_error_limit):
                    logging.info('Too    many    connection    errors    to    %s,    retrying    another    URL', self.active_base_url)
                    self.active_base_url = None
                    raise e
                logging.debug('Unable    to    connect    to    frontend.    Backing    off    %s    seconds.', self.error_poll_min)
                self.Wait(self.error_poll_min)
            else:
                raise e
