summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2015-02-11 17:10:33 +0000
committerErik Johnston <erik@matrix.org>2015-02-11 17:10:33 +0000
commitc52e8d395be2e6bc7bd2e768cd3fdc18df448603 (patch)
tree76a07d178fcbe350bc6f2046b05a045e00bdaaf2
parentMerge pull request #62 from matrix-org/state-chache (diff)
parentFix so timing out connections to actually work. (diff)
downloadsynapse-c52e8d395be2e6bc7bd2e768cd3fdc18df448603.tar.xz
Merge pull request #61 from matrix-org/timeout-federation-requests
Timeout federation requests
-rw-r--r--synapse/federation/replication.py2
-rw-r--r--synapse/http/matrixfederationclient.py8
-rw-r--r--synapse/util/__init__.py55
3 files changed, 63 insertions, 2 deletions
diff --git a/synapse/federation/replication.py b/synapse/federation/replication.py
index e442c6c5d5..54a0c7ad8e 100644
--- a/synapse/federation/replication.py
+++ b/synapse/federation/replication.py
@@ -72,5 +72,7 @@ class ReplicationLayer(FederationClient, FederationServer):
 
         self._order = 0
 
+        self.hs = hs
+
     def __str__(self):
         return "<ReplicationLayer(%s)>" % self.server_name
diff --git a/synapse/http/matrixfederationclient.py b/synapse/http/matrixfederationclient.py
index 406203acf2..1927948001 100644
--- a/synapse/http/matrixfederationclient.py
+++ b/synapse/http/matrixfederationclient.py
@@ -79,6 +79,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,
@@ -118,7 +119,7 @@ class MatrixFederationHttpClient(object):
 
             try:
                 with PreserveLoggingContext():
-                    response = yield self.agent.request(
+                    request_deferred = self.agent.request(
                         destination,
                         endpoint,
                         method,
@@ -129,6 +130,11 @@ class MatrixFederationHttpClient(object):
                         producer
                     )
 
+                    response = yield self.clock.time_bound_deferred(
+                        request_deferred,
+                        time_out=60,
+                    )
+
                 logger.debug("Got response to %s", method)
                 break
             except Exception as e:
diff --git a/synapse/util/__init__.py b/synapse/util/__init__.py
index fee76b0a9b..e77eba90ad 100644
--- a/synapse/util/__init__.py
+++ b/synapse/util/__init__.py
@@ -15,9 +15,12 @@
 
 from synapse.util.logcontext import LoggingContext
 
-from twisted.internet import reactor, task
+from twisted.internet import defer, reactor, task
 
 import time
+import logging
+
+logger = logging.getLogger(__name__)
 
 
 class Clock(object):
@@ -53,3 +56,53 @@ class Clock(object):
 
     def cancel_call_later(self, timer):
         timer.cancel()
+
+    def time_bound_deferred(self, given_deferred, time_out):
+        if given_deferred.called:
+            return given_deferred
+
+        ret_deferred = defer.Deferred()
+
+        def timed_out_fn():
+            try:
+                ret_deferred.errback(RuntimeError("Timed out"))
+            except:
+                pass
+
+            try:
+                given_deferred.cancel()
+            except:
+                pass
+
+        timer = None
+
+        def cancel(res):
+            try:
+                self.cancel_call_later(timer)
+            except:
+                pass
+            return res
+
+        ret_deferred.addBoth(cancel)
+
+        def sucess(res):
+            try:
+                ret_deferred.callback(res)
+            except:
+                pass
+
+            return res
+
+        def err(res):
+            try:
+                ret_deferred.errback(res)
+            except:
+                pass
+
+            return res
+
+        given_deferred.addCallbacks(callback=sucess, errback=err)
+
+        timer = self.call_later(time_out, timed_out_fn)
+
+        return ret_deferred