Add delay/retry logic for Failed http requests
* Adds delay/retry logic to accomodate HTTP failures/disconnects from server
This commit is contained in:
parent
f09a5718d4
commit
e727be8463
|
@ -35,7 +35,7 @@ class HTTPClient(object):
|
||||||
USER_AGENT = 'python-seamicroclient'
|
USER_AGENT = 'python-seamicroclient'
|
||||||
|
|
||||||
def __init__(self, user, password, auth_url=None,
|
def __init__(self, user, password, auth_url=None,
|
||||||
timeout=None, http_log_debug=False):
|
timeout=None, http_log_debug=False, retries=3):
|
||||||
self.user = user
|
self.user = user
|
||||||
self.password = password
|
self.password = password
|
||||||
self.api_endpoint = auth_url
|
self.api_endpoint = auth_url
|
||||||
|
@ -46,6 +46,7 @@ class HTTPClient(object):
|
||||||
self.timeout = float(timeout)
|
self.timeout = float(timeout)
|
||||||
else:
|
else:
|
||||||
self.timeout = None
|
self.timeout = None
|
||||||
|
self.retries = int(retries)
|
||||||
|
|
||||||
self.times = [] # [("item", starttime, endtime), ...]
|
self.times = [] # [("item", starttime, endtime), ...]
|
||||||
|
|
||||||
|
@ -62,8 +63,6 @@ class HTTPClient(object):
|
||||||
# have to set it up here on WARNING (its original level)
|
# have to set it up here on WARNING (its original level)
|
||||||
# otherwise we will get all the requests logging messanges
|
# otherwise we will get all the requests logging messanges
|
||||||
rql.setLevel(logging.WARNING)
|
rql.setLevel(logging.WARNING)
|
||||||
# requests within the same session can reuse TCP connections from pool
|
|
||||||
self.http = requests.Session()
|
|
||||||
|
|
||||||
def get_timings(self):
|
def get_timings(self):
|
||||||
return self.times
|
return self.times
|
||||||
|
@ -109,7 +108,7 @@ class HTTPClient(object):
|
||||||
kwargs.setdefault('timeout', self.timeout)
|
kwargs.setdefault('timeout', self.timeout)
|
||||||
|
|
||||||
self.http_log_req(method, url, kwargs)
|
self.http_log_req(method, url, kwargs)
|
||||||
resp = self.http.request(
|
resp = requests.request(
|
||||||
method,
|
method,
|
||||||
url,
|
url,
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
@ -144,16 +143,31 @@ class HTTPClient(object):
|
||||||
return resp, body
|
return resp, body
|
||||||
|
|
||||||
def _cs_request(self, url, method, **kwargs):
|
def _cs_request(self, url, method, **kwargs):
|
||||||
if method in ['GET', 'DELETE']:
|
attempts = 0
|
||||||
url = "%s?username=%s&password=%s" % (url, self.user,
|
retry_delay = 5
|
||||||
self.password)
|
while True:
|
||||||
else:
|
attempts += 1
|
||||||
kwargs.setdefault('body', {}).update({'username': self.user,
|
if method in ['GET', 'DELETE']:
|
||||||
'password': self.password})
|
url = "%s?username=%s&password=%s" % (url, self.user,
|
||||||
|
self.password)
|
||||||
resp, body = self._time_request(self.api_endpoint + url, method,
|
else:
|
||||||
**kwargs)
|
kwargs.setdefault('body', {}).update({'username': self.user,
|
||||||
return resp, body
|
'password': self.password})
|
||||||
|
try:
|
||||||
|
resp, body = self._time_request(self.api_endpoint + url,
|
||||||
|
method,**kwargs)
|
||||||
|
return resp, body
|
||||||
|
except requests.exceptions.ConnectionError as e:
|
||||||
|
if attempts > self.retries:
|
||||||
|
raise
|
||||||
|
# Catch a connection refused from requests.request
|
||||||
|
# retry again with some time delay
|
||||||
|
self._logger.debug("Connection refused: %s" % e)
|
||||||
|
self._logger.debug("Failed attempt(%s of %s), "
|
||||||
|
"retrying in %s seconds" %
|
||||||
|
(attempts, self.retries,
|
||||||
|
retry_delay))
|
||||||
|
time.sleep(retry_delay)
|
||||||
|
|
||||||
def get(self, url, **kwargs):
|
def get(self, url, **kwargs):
|
||||||
return self._cs_request(url, 'GET', **kwargs)
|
return self._cs_request(url, 'GET', **kwargs)
|
||||||
|
|
Loading…
Reference in New Issue