diff options
| author | Vishvananda Ishaya <vishvananda@gmail.com> | 2013-03-06 12:10:25 -0800 |
|---|---|---|
| committer | Vishvananda Ishaya <vishvananda@gmail.com> | 2013-03-12 14:50:07 -0700 |
| commit | 9bb29b9dff4d220eaabf86cd286e651c5ae15b98 (patch) | |
| tree | da50eabe3d1ff96eb8ba81f0ad6f355f9e931ed5 /keystoneclient | |
| parent | d782a998474d92d4299b4404b69442f0288efc3b (diff) | |
| download | python-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.py | 49 |
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: |
