summary refs log tree commit diff
path: root/synapse/storage/_base.py
diff options
context:
space:
mode:
authorPaul "LeoNerd" Evans <paul@matrix.org>2015-02-19 17:29:39 +0000
committerPaul "LeoNerd" Evans <paul@matrix.org>2015-02-19 17:29:39 +0000
commit077d20034278ea57c57d501de11bfb1f0c7f9603 (patch)
tree3af364a930c06ba8cb3c1bdaa825d762ac2ae2b2 /synapse/storage/_base.py
parentPull out the 'get_rooms_for_user' cache logic into a reĆ¼sable @cached decorator (diff)
downloadsynapse-077d20034278ea57c57d501de11bfb1f0c7f9603.tar.xz
Move @cached decorator out into synapse.storage._base; add minimal docs
Diffstat (limited to 'synapse/storage/_base.py')
-rw-r--r--synapse/storage/_base.py35
1 files changed, 35 insertions, 0 deletions
diff --git a/synapse/storage/_base.py b/synapse/storage/_base.py
index be9934c66f..fd275039be 100644
--- a/synapse/storage/_base.py
+++ b/synapse/storage/_base.py
@@ -35,6 +35,41 @@ sql_logger = logging.getLogger("synapse.storage.SQL")
 transaction_logger = logging.getLogger("synapse.storage.txn")
 
 
+# TODO(paul):
+#  * Move this somewhere higher-level, shared;
+#  * more generic key management
+#  * export monitoring stats
+#  * maximum size; just evict things at random, or consider LRU?
+def cached(orig):
+    """ A method decorator that applies a memoizing cache around the function.
+
+    The function is presumed to take one additional argument, which is used as
+    the key for the cache. Cache hits are served directly from the cache;
+    misses use the function body to generate the value.
+
+    The wrapped function has an additional member, a callable called
+    "invalidate". This can be used to remove individual entries from the cache.
+    """
+    cache = {}
+
+    @defer.inlineCallbacks
+    def wrapped(self, key):
+        if key in cache:
+            defer.returnValue(cache[key])
+
+        ret = yield orig(self, key)
+
+        cache[key] = ret;
+        defer.returnValue(ret)
+
+    def invalidate(key):
+        if key in cache:
+            del cache[key]
+
+    wrapped.invalidate = invalidate
+    return wrapped
+
+
 class LoggingTransaction(object):
     """An object that almost-transparently proxies for the 'txn' object
     passed to the constructor. Adds logging to the .execute() method."""