summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2015-02-10 18:17:27 +0000
committerErik Johnston <erik@matrix.org>2015-02-10 18:17:27 +0000
commit0e6b3e4e40ae918eacdef87bb50ff1d19b304e7c (patch)
treed852ed68f2bd8d60a5b8cb7cc313ed3f48b65e35
parentMerge pull request #59 from matrix-org/hotfixes-v0.6.1f (diff)
downloadsynapse-0e6b3e4e40ae918eacdef87bb50ff1d19b304e7c.tar.xz
Time out HTTP federation requests
-rw-r--r--synapse/http/matrixfederationclient.py11
-rw-r--r--synapse/util/async.py20
2 files changed, 29 insertions, 2 deletions
diff --git a/synapse/http/matrixfederationclient.py b/synapse/http/matrixfederationclient.py
index aa14782b0f..fdc1e2678e 100644
--- a/synapse/http/matrixfederationclient.py
+++ b/synapse/http/matrixfederationclient.py
@@ -22,7 +22,7 @@ from twisted.web._newclient import ResponseDone
 
 from synapse.http.agent_name import AGENT_NAME
 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 syutil.jsonutil import encode_canonical_json
@@ -78,6 +78,7 @@ class MatrixFederationHttpClient(object):
         self.signing_key = hs.config.signing_key[0]
         self.server_name = hs.hostname
         self.agent = MatrixFederationHttpAgent(reactor)
+        self.clock = hs.get_clock()
 
     @defer.inlineCallbacks
     def _create_request(self, destination, method, path_bytes,
@@ -117,7 +118,7 @@ class MatrixFederationHttpClient(object):
 
             try:
                 with PreserveLoggingContext():
-                    response = yield self.agent.request(
+                    request_deferred = self.agent.request(
                         destination,
                         endpoint,
                         method,
@@ -128,6 +129,12 @@ class MatrixFederationHttpClient(object):
                         producer
                     )
 
+                    response = yield time_bound_deferred(
+                        request_deferred,
+                        clock=self.clock,
+                        time_out=60,
+                    )
+
                 logger.debug("Got response to %s", method)
                 break
             except Exception as e:
diff --git a/synapse/util/async.py b/synapse/util/async.py
index c4fe5d522f..d4d1d4b472 100644
--- a/synapse/util/async.py
+++ b/synapse/util/async.py
@@ -32,3 +32,23 @@ def run_on_reactor():
     iteration of the main loop
     """
     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