summary refs log tree commit diff
diff options
context:
space:
mode:
authorRichard van der Hoff <1389908+richvdh@users.noreply.github.com>2020-10-21 22:57:23 +0100
committerGitHub <noreply@github.com>2020-10-21 22:57:23 +0100
commit15d5553d9e3a270d2ad6d02c9d3df9152732876d (patch)
tree23f500efd69e4d39ca593ebc9c13560f1a155df4
parentMerge pull request #8572 from matrix-org/rav/cache_hacking/2 (diff)
parentfix failure case (diff)
downloadsynapse-15d5553d9e3a270d2ad6d02c9d3df9152732876d.tar.xz
Merge pull request #8593 from matrix-org/rav/cache_hacking/3
Optimisation in DeferredCache.set
-rw-r--r--changelog.d/8593.misc1
-rw-r--r--synapse/util/caches/deferred_cache.py18
2 files changed, 16 insertions, 3 deletions
diff --git a/changelog.d/8593.misc b/changelog.d/8593.misc
new file mode 100644
index 0000000000..d266ba19a4
--- /dev/null
+++ b/changelog.d/8593.misc
@@ -0,0 +1 @@
+Minor optimisations in caching code.
diff --git a/synapse/util/caches/deferred_cache.py b/synapse/util/caches/deferred_cache.py
index 6c162e9f34..601305487c 100644
--- a/synapse/util/caches/deferred_cache.py
+++ b/synapse/util/caches/deferred_cache.py
@@ -31,6 +31,7 @@ from typing import (
 from prometheus_client import Gauge
 
 from twisted.internet import defer
+from twisted.python import failure
 
 from synapse.util.async_helpers import ObservableDeferred
 from synapse.util.caches.lrucache import LruCache
@@ -214,9 +215,6 @@ class DeferredCache(Generic[KT, VT]):
 
         callbacks = [callback] if callback else []
         self.check_thread()
-        observable = ObservableDeferred(value, consumeErrors=True)
-        observer = observable.observe()
-        entry = CacheEntry(deferred=observable, callbacks=callbacks)
 
         existing_entry = self._pending_deferred_cache.pop(key, None)
         if existing_entry:
@@ -224,6 +222,20 @@ class DeferredCache(Generic[KT, VT]):
 
         # XXX: why don't we invalidate the entry in `self.cache` yet?
 
+        # we can save a whole load of effort if the deferred is ready.
+        if value.called:
+            result = value.result
+            if not isinstance(result, failure.Failure):
+                self.cache.set(key, result, callbacks)
+            return value
+
+        # otherwise, we'll add an entry to the _pending_deferred_cache for now,
+        # and add callbacks to add it to the cache properly later.
+
+        observable = ObservableDeferred(value, consumeErrors=True)
+        observer = observable.observe()
+        entry = CacheEntry(deferred=observable, callbacks=callbacks)
+
         self._pending_deferred_cache[key] = entry
 
         def compare_and_pop():