Make retrying requests on DNS failures configurable, and turn off retrying only in directory.get_association

This commit is contained in:
Kegan Dougal 2014-09-03 14:26:35 +01:00
parent c06d07a276
commit 7fc84c7019
3 changed files with 29 additions and 8 deletions

View file

@ -18,6 +18,7 @@ from twisted.internet import defer
from ._base import BaseHandler from ._base import BaseHandler
from synapse.api.errors import SynapseError from synapse.api.errors import SynapseError
from synapse.http.client import HttpClient
import logging import logging
@ -68,7 +69,10 @@ class DirectoryHandler(BaseHandler):
result = yield self.federation.make_query( result = yield self.federation.make_query(
destination=room_alias.domain, destination=room_alias.domain,
query_type="directory", query_type="directory",
args={"room_alias": room_alias.to_string()}, args={
"room_alias": room_alias.to_string(),
HttpClient.RETRY_DNS_LOOKUP_FAILURES: False
}
) )
if result and "room_id" in result and "servers" in result: if result and "room_id" in result and "servers" in result:

View file

@ -44,6 +44,7 @@ _destination_mappings = {
class HttpClient(object): class HttpClient(object):
""" Interface for talking json over http """ Interface for talking json over http
""" """
RETRY_DNS_LOOKUP_FAILURES = "__retry_dns"
def put_json(self, destination, path, data): def put_json(self, destination, path, data):
""" Sends the specifed json data using PUT """ Sends the specifed json data using PUT
@ -143,13 +144,23 @@ class TwistedHttpClient(HttpClient):
destination = _destination_mappings[destination] destination = _destination_mappings[destination]
logger.debug("get_json args: %s", args) logger.debug("get_json args: %s", args)
retry_on_dns_fail = True
if HttpClient.RETRY_DNS_LOOKUP_FAILURES in args:
# FIXME: This isn't ideal, but the interface exposed in get_json
# isn't comprehensive enough to give caller's any control over
# their connection mechanics.
retry_on_dns_fail = args.pop(HttpClient.RETRY_DNS_LOOKUP_FAILURES)
query_bytes = urllib.urlencode(args, True) query_bytes = urllib.urlencode(args, True)
logger.debug("Query bytes: %s Retry DNS: %s", args, retry_on_dns_fail)
response = yield self._create_request( response = yield self._create_request(
destination.encode("ascii"), destination.encode("ascii"),
"GET", "GET",
path.encode("ascii"), path.encode("ascii"),
query_bytes=query_bytes query_bytes=query_bytes,
retry_on_dns_fail=retry_on_dns_fail
) )
body = yield readBody(response) body = yield readBody(response)
@ -158,7 +169,8 @@ class TwistedHttpClient(HttpClient):
@defer.inlineCallbacks @defer.inlineCallbacks
def _create_request(self, destination, method, path_bytes, param_bytes=b"", def _create_request(self, destination, method, path_bytes, param_bytes=b"",
query_bytes=b"", producer=None, headers_dict={}): query_bytes=b"", producer=None, headers_dict={},
retry_on_dns_fail=True):
""" Creates and sends a request to the given url """ Creates and sends a request to the given url
""" """
headers_dict[b"User-Agent"] = [b"Synapse"] headers_dict[b"User-Agent"] = [b"Synapse"]
@ -199,11 +211,12 @@ class TwistedHttpClient(HttpClient):
logger.debug("Got response to %s", method) logger.debug("Got response to %s", method)
break break
except DNSLookupError as dns:
logger.warn("DNS Lookup failed to %s with %s", destination,
dns)
raise SynapseError(400, "Domain specified not found.")
except Exception as e: except Exception as e:
if not retry_on_dns_fail and isinstance(e, DNSLookupError):
logger.warn("DNS Lookup failed to %s with %s", destination,
e)
raise SynapseError(400, "Domain specified not found.")
logger.exception("Got error in _create_request") logger.exception("Got error in _create_request")
_print_ex(e) _print_ex(e)

View file

@ -21,6 +21,7 @@ from mock import Mock
import logging import logging
from synapse.server import HomeServer from synapse.server import HomeServer
from synapse.http.client import HttpClient
from synapse.handlers.directory import DirectoryHandler from synapse.handlers.directory import DirectoryHandler
from synapse.storage.directory import RoomAliasMapping from synapse.storage.directory import RoomAliasMapping
@ -92,7 +93,10 @@ class DirectoryTestCase(unittest.TestCase):
self.mock_federation.make_query.assert_called_with( self.mock_federation.make_query.assert_called_with(
destination="remote", destination="remote",
query_type="directory", query_type="directory",
args={"room_alias": "#another:remote"} args={
"room_alias": "#another:remote",
HttpClient.RETRY_DNS_LOOKUP_FAILURES: False
}
) )
@defer.inlineCallbacks @defer.inlineCallbacks