forked from MirrorHub/synapse
Make retrying requests on DNS failures configurable, and turn off retrying only in directory.get_association
This commit is contained in:
parent
c06d07a276
commit
7fc84c7019
3 changed files with 29 additions and 8 deletions
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue