Time out HTTP federation requests

This commit is contained in:
Erik Johnston 2015-02-10 18:17:27 +00:00
parent 771892b314
commit 0e6b3e4e40
2 changed files with 29 additions and 2 deletions

View File

@ -22,7 +22,7 @@ from twisted.web._newclient import ResponseDone
from synapse.http.agent_name import AGENT_NAME from synapse.http.agent_name import AGENT_NAME
from synapse.http.endpoint import matrix_federation_endpoint from synapse.http.endpoint import matrix_federation_endpoint
from synapse.util.async import sleep from synapse.util.async import sleep, time_bound_deferred
from synapse.util.logcontext import PreserveLoggingContext from synapse.util.logcontext import PreserveLoggingContext
from syutil.jsonutil import encode_canonical_json from syutil.jsonutil import encode_canonical_json
@ -78,6 +78,7 @@ class MatrixFederationHttpClient(object):
self.signing_key = hs.config.signing_key[0] self.signing_key = hs.config.signing_key[0]
self.server_name = hs.hostname self.server_name = hs.hostname
self.agent = MatrixFederationHttpAgent(reactor) self.agent = MatrixFederationHttpAgent(reactor)
self.clock = hs.get_clock()
@defer.inlineCallbacks @defer.inlineCallbacks
def _create_request(self, destination, method, path_bytes, def _create_request(self, destination, method, path_bytes,
@ -117,7 +118,7 @@ class MatrixFederationHttpClient(object):
try: try:
with PreserveLoggingContext(): with PreserveLoggingContext():
response = yield self.agent.request( request_deferred = self.agent.request(
destination, destination,
endpoint, endpoint,
method, method,
@ -128,6 +129,12 @@ class MatrixFederationHttpClient(object):
producer producer
) )
response = yield time_bound_deferred(
request_deferred,
clock=self.clock,
time_out=60,
)
logger.debug("Got response to %s", method) logger.debug("Got response to %s", method)
break break
except Exception as e: except Exception as e:

View File

@ -32,3 +32,23 @@ def run_on_reactor():
iteration of the main loop iteration of the main loop
""" """
return sleep(0) return sleep(0)
def time_bound_deferred(given_deferred, clock, time_out):
ret_deferred = defer.Deferred()
def timed_out():
if not given_deferred.called:
given_deferred.cancel()
ret_deferred.errback(RuntimeError("Timed out"))
timer = clock.call_later(time_out, timed_out)
def succeed(result):
clock.cancel_call_later(timer)
ret_deferred.callback(result)
given_deferred.addCallback(succeed)
given_deferred.addErrback(ret_deferred.errback)
return ret_deferred