summary refs log tree commit diff
path: root/synapse/util/caches/expiringcache.py
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2018-09-21 16:25:42 +0100
committerErik Johnston <erik@matrix.org>2018-09-21 16:25:42 +0100
commit19dc676d1aaf66a45c9a1810132952f7ae3ca2aa (patch)
tree04a27a9db8702e58f6c9a989c121b97821b6c520 /synapse/util/caches/expiringcache.py
parentNewsfile (diff)
downloadsynapse-19dc676d1aaf66a45c9a1810132952f7ae3ca2aa.tar.xz
Fix ExpiringCache.__len__ to be accurate
It used to try and produce an estimate, which was sometimes negative.
This caused metrics to be sad, so lets always just calculate it from
scratch.
Diffstat (limited to 'synapse/util/caches/expiringcache.py')
-rw-r--r--synapse/util/caches/expiringcache.py21
1 files changed, 9 insertions, 12 deletions
diff --git a/synapse/util/caches/expiringcache.py b/synapse/util/caches/expiringcache.py
index 346669e4ce..8ac56d85ff 100644
--- a/synapse/util/caches/expiringcache.py
+++ b/synapse/util/caches/expiringcache.py
@@ -16,7 +16,7 @@
 import logging
 from collections import OrderedDict
 
-from six import iteritems
+from six import iteritems, itervalues
 
 from synapse.metrics.background_process_metrics import run_as_background_process
 from synapse.util.caches import register_cache
@@ -59,8 +59,6 @@ class ExpiringCache(object):
 
         self.iterable = iterable
 
-        self._size_estimate = 0
-
         self.metrics = register_cache("expiring", cache_name, self)
 
         if not self._expiry_ms:
@@ -79,16 +77,11 @@ class ExpiringCache(object):
         now = self._clock.time_msec()
         self._cache[key] = _CacheEntry(now, value)
 
-        if self.iterable:
-            self._size_estimate += len(value)
-
         # Evict if there are now too many items
         while self._max_len and len(self) > self._max_len:
             _key, value = self._cache.popitem(last=False)
             if self.iterable:
-                removed_len = len(value.value)
-                self.metrics.inc_evictions(removed_len)
-                self._size_estimate -= removed_len
+                self.metrics.inc_evictions(len(value.value))
             else:
                 self.metrics.inc_evictions()
 
@@ -111,7 +104,9 @@ class ExpiringCache(object):
             return default
 
         if self.iterable:
-            self._size_estimate -= len(value.value)
+            self.metrics.inc_evictions(len(value.value))
+        else:
+            self.metrics.inc_evictions()
 
         return value
 
@@ -149,7 +144,9 @@ class ExpiringCache(object):
         for k in keys_to_delete:
             value = self._cache.pop(k)
             if self.iterable:
-                self._size_estimate -= len(value.value)
+                self.metrics.inc_evictions(len(value.value))
+            else:
+                self.metrics.inc_evictions()
 
         logger.debug(
             "[%s] _prune_cache before: %d, after len: %d",
@@ -158,7 +155,7 @@ class ExpiringCache(object):
 
     def __len__(self):
         if self.iterable:
-            return self._size_estimate
+            return sum(len(entry.value) for entry in itervalues(self._cache))
         else:
             return len(self._cache)