summaryrefslogtreecommitdiff
path: root/keystoneclient
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@gmail.com>2013-03-06 12:10:25 -0800
committerVishvananda Ishaya <vishvananda@gmail.com>2013-03-12 14:50:07 -0700
commit9bb29b9dff4d220eaabf86cd286e651c5ae15b98 (patch)
treeda50eabe3d1ff96eb8ba81f0ad6f355f9e931ed5 /keystoneclient
parentd782a998474d92d4299b4404b69442f0288efc3b (diff)
downloadpython-keystoneclient-9bb29b9dff4d220eaabf86cd286e651c5ae15b98.tar.gz
Retry http_request and json_request failure.
Temporary network outages or keystone server restarts can lead to a connection refused in auth_token middleware. Rather than failing immediately, this patch attempts to retry a few times. Fixes bug 1150299 Change-Id: I2ecf0d7745290976efcb3e3cd6511817a53d3e0a
Diffstat (limited to 'keystoneclient')
-rw-r--r--keystoneclient/middleware/auth_token.py49
1 files changed, 26 insertions, 23 deletions
diff --git a/keystoneclient/middleware/auth_token.py b/keystoneclient/middleware/auth_token.py
index 084d6f2..df65689 100644
--- a/keystoneclient/middleware/auth_token.py
+++ b/keystoneclient/middleware/auth_token.py
@@ -559,25 +559,36 @@ class AuthProtocol(object):
self.cert_file,
timeout=self.http_connect_timeout)
- def _http_request(self, method, path):
+ def _http_request(self, method, path, **kwargs):
"""HTTP request helper used to make unspecified content type requests.
:param method: http method
:param path: relative request url
- :return (http response object)
+ :return (http response object, response body)
:raise ServerError when unable to communicate with keystone
"""
conn = self._get_http_connection()
- try:
- conn.request(method, path)
- response = conn.getresponse()
- body = response.read()
- except Exception as e:
- self.LOG.error('HTTP connection exception: %s' % e)
- raise ServiceError('Unable to communicate with keystone')
- finally:
- conn.close()
+
+ RETRIES = 3
+ retry = 0
+
+ while True:
+ try:
+ conn.request(method, path, **kwargs)
+ response = conn.getresponse()
+ body = response.read()
+ break
+ except Exception as e:
+ if retry == RETRIES:
+ self.LOG.error('HTTP connection exception: %s' % e)
+ raise ServiceError('Unable to communicate with keystone')
+ # NOTE(vish): sleep 0.5, 1, 2
+ self.LOG.warn('Retrying on HTTP connection exception: %s' % e)
+ time.sleep(2.0 ** retry / 2)
+ retry += 1
+ finally:
+ conn.close()
return response, body
@@ -593,8 +604,6 @@ class AuthProtocol(object):
:raise ServerError when unable to communicate with keystone
"""
- conn = self._get_http_connection()
-
kwargs = {
'headers': {
'Content-type': 'application/json',
@@ -608,16 +617,10 @@ class AuthProtocol(object):
if body:
kwargs['body'] = jsonutils.dumps(body)
- full_path = self.auth_admin_prefix + path
- try:
- conn.request(method, full_path, **kwargs)
- response = conn.getresponse()
- body = response.read()
- except Exception as e:
- self.LOG.error('HTTP connection exception: %s' % e)
- raise ServiceError('Unable to communicate with keystone')
- finally:
- conn.close()
+ path = self.auth_admin_prefix + path
+
+ response, body = self._http_request(method, path, **kwargs)
+
try:
data = jsonutils.loads(body)
except ValueError: