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.
This commit is contained in:
Erik Johnston 2018-09-21 16:25:42 +01:00
parent 5230bc1471
commit 19dc676d1a

View File

@ -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)