diff options
author | Erik Johnston <erik@matrix.org> | 2018-03-15 15:40:13 +0000 |
---|---|---|
committer | Erik Johnston <erik@matrix.org> | 2018-03-15 15:46:54 +0000 |
commit | 7c7706f42b56dd61f5eb17679aa12247f7058ed5 (patch) | |
tree | 5d45938bcff322833a04e8f072507f7fcdb71b81 | |
parent | Merge pull request #3003 from matrix-org/rav/fix_contributing (diff) | |
download | synapse-7c7706f42b56dd61f5eb17679aa12247f7058ed5.tar.xz |
Fix bug where state cache used lots of memory
The state cache bases its size on the sum of the size of entries. The size of the entry is calculated once on insertion, so it is important that the size of entries does not change. The DictionaryCache modified the entries size, which caused the state cache to incorrectly think it was smaller than it actually was.
-rw-r--r-- | synapse/util/caches/dictionary_cache.py | 6 | ||||
-rw-r--r-- | synapse/util/caches/lrucache.py | 8 |
2 files changed, 9 insertions, 5 deletions
diff --git a/synapse/util/caches/dictionary_cache.py b/synapse/util/caches/dictionary_cache.py index d4105822b3..1709e8b429 100644 --- a/synapse/util/caches/dictionary_cache.py +++ b/synapse/util/caches/dictionary_cache.py @@ -132,9 +132,13 @@ class DictionaryCache(object): self._update_or_insert(key, value, known_absent) def _update_or_insert(self, key, value, known_absent): - entry = self.cache.setdefault(key, DictionaryEntry(False, set(), {})) + # We pop and reinsert as we need to tell the cache the size may have + # changed + + entry = self.cache.pop(key, DictionaryEntry(False, set(), {})) entry.value.update(value) entry.known_absent.update(known_absent) + self.cache[key] = entry def _insert(self, key, value, known_absent): self.cache[key] = DictionaryEntry(True, known_absent, value) diff --git a/synapse/util/caches/lrucache.py b/synapse/util/caches/lrucache.py index f088dd430e..a4bf8fa6ae 100644 --- a/synapse/util/caches/lrucache.py +++ b/synapse/util/caches/lrucache.py @@ -154,14 +154,14 @@ class LruCache(object): def cache_set(key, value, callbacks=[]): node = cache.get(key, None) if node is not None: - if value != node.value: + if node.callbacks and value != node.value: for cb in node.callbacks: cb() node.callbacks.clear() - if size_callback: - cached_cache_len[0] -= size_callback(node.value) - cached_cache_len[0] += size_callback(value) + if size_callback: + cached_cache_len[0] -= size_callback(node.value) + cached_cache_len[0] += size_callback(value) node.callbacks.update(callbacks) |