summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2021-03-26 17:38:50 +0000
committerErik Johnston <erik@matrix.org>2021-03-26 17:38:50 +0000
commitf38350fdda1dcd6c1b68f876b22480e337219255 (patch)
treef6383543a9a3f871551c0473758fd27385c69649 /synapse
parentMake it possible to use dmypy (#9692) (diff)
downloadsynapse-f38350fdda1dcd6c1b68f876b22480e337219255.tar.xz
Report cache memory usage
Diffstat (limited to 'synapse')
-rw-r--r--synapse/util/caches/__init__.py3
-rw-r--r--synapse/util/caches/lrucache.py23
2 files changed, 23 insertions, 3 deletions
diff --git a/synapse/util/caches/__init__.py b/synapse/util/caches/__init__.py
index 48f64eeb38..2ab6aba260 100644
--- a/synapse/util/caches/__init__.py
+++ b/synapse/util/caches/__init__.py
@@ -33,6 +33,7 @@ cache_hits = Gauge("synapse_util_caches_cache:hits", "", ["name"])
 cache_evicted = Gauge("synapse_util_caches_cache:evicted_size", "", ["name"])
 cache_total = Gauge("synapse_util_caches_cache:total", "", ["name"])
 cache_max_size = Gauge("synapse_util_caches_cache_max_size", "", ["name"])
+cache_memory_usage = Gauge("synapse_util_caches_cache_memory_usage", "", ["name"])
 
 response_cache_size = Gauge("synapse_util_caches_response_cache:size", "", ["name"])
 response_cache_hits = Gauge("synapse_util_caches_response_cache:hits", "", ["name"])
@@ -53,6 +54,7 @@ class CacheMetric:
     hits = attr.ib(default=0)
     misses = attr.ib(default=0)
     evicted_size = attr.ib(default=0)
+    memory_usage = attr.ib(default=0)
 
     def inc_hits(self):
         self.hits += 1
@@ -80,6 +82,7 @@ class CacheMetric:
                 cache_hits.labels(self._cache_name).set(self.hits)
                 cache_evicted.labels(self._cache_name).set(self.evicted_size)
                 cache_total.labels(self._cache_name).set(self.hits + self.misses)
+                cache_memory_usage.labels(self._cache_name).set(self.memory_usage)
                 if getattr(self._cache, "max_size", None):
                     cache_max_size.labels(self._cache_name).set(self._cache.max_size)
             if self._collect_callback:
diff --git a/synapse/util/caches/lrucache.py b/synapse/util/caches/lrucache.py
index 60bb6ff642..570bcac1fd 100644
--- a/synapse/util/caches/lrucache.py
+++ b/synapse/util/caches/lrucache.py
@@ -34,6 +34,11 @@ from synapse.config import cache as cache_config
 from synapse.util.caches import CacheMetric, register_cache
 from synapse.util.caches.treecache import TreeCache
 
+try:
+    from pympler import asizeof
+except ImportError:
+    asizeof = None
+
 # Function type: the type used for invalidation callbacks
 FT = TypeVar("FT", bound=Callable[..., Any])
 
@@ -55,15 +60,21 @@ def enumerate_leaves(node, depth):
 
 
 class _Node:
-    __slots__ = ["prev_node", "next_node", "key", "value", "callbacks"]
+    __slots__ = ["prev_node", "next_node", "key", "value", "callbacks", "memory"]
 
     def __init__(self, prev_node, next_node, key, value, callbacks=set()):
-        self.prev_node = prev_node
-        self.next_node = next_node
         self.key = key
         self.value = value
         self.callbacks = callbacks
 
+        if asizeof:
+            self.memory = asizeof.asizeof(self)
+        else:
+            self.memory = 0
+
+        self.prev_node = prev_node
+        self.next_node = next_node
+
 
 class LruCache(Generic[KT, VT]):
     """
@@ -184,6 +195,9 @@ class LruCache(Generic[KT, VT]):
             next_node.prev_node = node
             cache[key] = node
 
+            if metrics:
+                metrics.memory_usage += node.memory
+
             if size_callback:
                 cached_cache_len[0] += size_callback(node.value)
 
@@ -205,6 +219,9 @@ class LruCache(Generic[KT, VT]):
             prev_node.next_node = next_node
             next_node.prev_node = prev_node
 
+            if metrics:
+                metrics.memory_usage -= node.memory
+
             deleted_len = 1
             if size_callback:
                 deleted_len = size_callback(node.value)