Timeout should not trigger a retry by default

This commit is contained in:
Honza Král
2014-11-10 23:52:26 +01:00
parent 2b107ece5c
commit d9296e85b9
3 changed files with 25 additions and 5 deletions
+6
View File
@@ -3,6 +3,12 @@
Changelog Changelog
========= =========
1.3.0 (dev)
-----------
* Timeout now doesn't trigger a retry by default (can be overriden by setting
`retry_on_timeout=True`)
1.2.0 (2014-08-03) 1.2.0 (2014-08-03)
------------------ ------------------
+3 -3
View File
@@ -3,7 +3,7 @@ import urllib3
from urllib3.exceptions import ReadTimeoutError from urllib3.exceptions import ReadTimeoutError
from .base import Connection from .base import Connection
from ..exceptions import ConnectionError from ..exceptions import ConnectionError, ConnectionTimeout
from ..compat import urlencode from ..compat import urlencode
class Urllib3HttpConnection(Connection): class Urllib3HttpConnection(Connection):
@@ -33,7 +33,7 @@ class Urllib3HttpConnection(Connection):
def perform_request(self, method, url, params=None, body=None, timeout=None, ignore=()): def perform_request(self, method, url, params=None, body=None, timeout=None, ignore=()):
url = self.url_prefix + url url = self.url_prefix + url
if params: if params:
url = '%s?%s' % (url, urlencode(params or {})) url = '%s?%s' % (url, urlencode(params))
full_url = self.host + url full_url = self.host + url
start = time.time() start = time.time()
@@ -52,7 +52,7 @@ class Urllib3HttpConnection(Connection):
raw_data = response.data.decode('utf-8') raw_data = response.data.decode('utf-8')
except ReadTimeoutError as e: except ReadTimeoutError as e:
self.log_request_fail(method, full_url, body, time.time() - start, exception=e) self.log_request_fail(method, full_url, body, time.time() - start, exception=e)
raise ConnectionError('TIMEOUT', str(e), e) raise ConnectionTimeout('TIMEOUT', str(e), e)
except Exception as e: except Exception as e:
self.log_request_fail(method, full_url, body, time.time() - start, exception=e) self.log_request_fail(method, full_url, body, time.time() - start, exception=e)
raise ConnectionError('N/A', str(e), e) raise ConnectionError('N/A', str(e), e)
+16 -2
View File
@@ -4,7 +4,8 @@ import time
from .connection import Urllib3HttpConnection from .connection import Urllib3HttpConnection
from .connection_pool import ConnectionPool from .connection_pool import ConnectionPool
from .serializer import JSONSerializer, Deserializer, DEFAULT_SERIALIZERS from .serializer import JSONSerializer, Deserializer, DEFAULT_SERIALIZERS
from .exceptions import ConnectionError, TransportError, SerializationError from .exceptions import ConnectionError, TransportError, SerializationError, \
ConnectionTimeout
# get ip/port from "inet[wind/127.0.0.1:9200]" # get ip/port from "inet[wind/127.0.0.1:9200]"
ADDRESS_RE = re.compile(r'/(?P<host>[\.:0-9a-f]*):(?P<port>[0-9]+)\]?$') ADDRESS_RE = re.compile(r'/(?P<host>[\.:0-9a-f]*):(?P<port>[0-9]+)\]?$')
@@ -45,7 +46,7 @@ class Transport(object):
sniff_on_start=False, sniffer_timeout=None, sniff_timeout=.1, sniff_on_start=False, sniffer_timeout=None, sniff_timeout=.1,
sniff_on_connection_fail=False, serializer=JSONSerializer(), serializers=None, sniff_on_connection_fail=False, serializer=JSONSerializer(), serializers=None,
default_mimetype='application/json', max_retries=3, default_mimetype='application/json', max_retries=3,
send_get_body_as='GET', **kwargs): retry_on_timeout=False, send_get_body_as='GET', **kwargs):
""" """
:arg hosts: list of dictionaries, each containing keyword arguments to :arg hosts: list of dictionaries, each containing keyword arguments to
create a `connection_class` instance create a `connection_class` instance
@@ -67,6 +68,8 @@ class Transport(object):
:arg default_mimetype: when no mimetype is specified by the server :arg default_mimetype: when no mimetype is specified by the server
response assume this mimetype, defaults to `'application/json'` response assume this mimetype, defaults to `'application/json'`
:arg max_retries: maximum number of retries before an exception is propagated :arg max_retries: maximum number of retries before an exception is propagated
:arg retry_on_timeout: should timeout trigger a retry on different
node? (default `False`)
:arg send_get_body_as: for GET requests with body this option allows :arg send_get_body_as: for GET requests with body this option allows
you to specify an alternate way of execution for environments that you to specify an alternate way of execution for environments that
don't support passing bodies with GET requests. If you set this to don't support passing bodies with GET requests. If you set this to
@@ -89,6 +92,7 @@ class Transport(object):
self.deserializer = Deserializer(_serializers, default_mimetype) self.deserializer = Deserializer(_serializers, default_mimetype)
self.max_retries = max_retries self.max_retries = max_retries
self.retry_on_timeout = retry_on_timeout
self.send_get_body_as = send_get_body_as self.send_get_body_as = send_get_body_as
# data serializer # data serializer
@@ -282,6 +286,16 @@ class Transport(object):
try: try:
status, headers, data = connection.perform_request(method, url, params, body, ignore=ignore, timeout=timeout) status, headers, data = connection.perform_request(method, url, params, body, ignore=ignore, timeout=timeout)
except ConnectionTimeout:
if self.retry_on_timeout:
# only mark as dead if we are retrying
self.mark_dead(connection)
# raise exception on last retry
if attempt == self.max_retries:
raise
else:
raise
except ConnectionError: except ConnectionError:
self.mark_dead(connection) self.mark_dead(connection)