diff --git a/synapse/util/__init__.py b/synapse/util/__init__.py
index c1a16b639a..260714ccc2 100644
--- a/synapse/util/__init__.py
+++ b/synapse/util/__init__.py
@@ -29,6 +29,34 @@ def unwrapFirstError(failure):
return failure.value.subFailure
+def unwrap_deferred(d):
+ """Given a deferred that we know has completed, return its value or raise
+ the failure as an exception
+ """
+ if not d.called:
+ raise RuntimeError("deferred has not finished")
+
+ res = []
+
+ def f(r):
+ res.append(r)
+ return r
+ d.addCallback(f)
+
+ if res:
+ return res[0]
+
+ def f(r):
+ res.append(r)
+ return r
+ d.addErrback(f)
+
+ if res:
+ res[0].raiseException()
+ else:
+ raise RuntimeError("deferred did not call callbacks")
+
+
class Clock(object):
"""A small utility that obtains current time-of-day so that time may be
mocked during unit-tests.
@@ -52,16 +80,16 @@ class Clock(object):
def stop_looping_call(self, loop):
loop.stop()
- def call_later(self, delay, callback):
+ def call_later(self, delay, callback, *args, **kwargs):
current_context = LoggingContext.current_context()
- def wrapped_callback():
+ def wrapped_callback(*args, **kwargs):
with PreserveLoggingContext():
LoggingContext.thread_local.current_context = current_context
- callback()
+ callback(*args, **kwargs)
with PreserveLoggingContext():
- return reactor.callLater(delay, wrapped_callback)
+ return reactor.callLater(delay, wrapped_callback, *args, **kwargs)
def cancel_call_later(self, timer):
timer.cancel()
diff --git a/synapse/util/lrucache.py b/synapse/util/lrucache.py
index 96163c90f1..cacd7e45fa 100644
--- a/synapse/util/lrucache.py
+++ b/synapse/util/lrucache.py
@@ -20,7 +20,6 @@ import threading
class LruCache(object):
"""Least-recently-used cache."""
- # TODO(mjark) Add mutex for linked list for thread safety.
def __init__(self, max_size):
cache = {}
list_root = []
@@ -106,6 +105,12 @@ class LruCache(object):
return default
@synchronized
+ def cache_clear():
+ list_root[NEXT] = list_root
+ list_root[PREV] = list_root
+ cache.clear()
+
+ @synchronized
def cache_len():
return len(cache)
@@ -120,6 +125,7 @@ class LruCache(object):
self.pop = cache_pop
self.len = cache_len
self.contains = cache_contains
+ self.clear = cache_clear
def __getitem__(self, key):
result = self.get(key, self.sentinel)
|