-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Fix bug where state cache used lots of memory #3005
Conversation
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.
synapse/util/caches/lrucache.py
Outdated
@@ -154,14 +154,14 @@ def cache_get(key, default=None, callbacks=[]): | |||
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: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, this was just a cheeky thing to only do the !=
check if we do actually have node.callbacks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be worth a comment then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't it outweighed by doing size_callback
even when it doesn't change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks fine modulo comments
synapse/util/caches/lrucache.py
Outdated
@@ -154,14 +154,14 @@ def cache_get(key, default=None, callbacks=[]): | |||
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: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be worth a comment then?
synapse/util/caches/lrucache.py
Outdated
@@ -154,14 +154,14 @@ def cache_get(key, default=None, callbacks=[]): | |||
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: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't it outweighed by doing size_callback
even when it doesn't change?
# We pop and reinsert as we need to tell the cache the size may have | ||
# changed | ||
|
||
entry = self.cache.pop(key, DictionaryEntry(False, set(), {})) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not entirely relevant here, but I wonder if it would be better to do
entry = self.cache.pop(key, None)
if entry is None:
entry = DictionaryEntry(False, set(), {})
to avoid the object creation overhead?
please can we merge this and cut a new RC before any more folks on 0.27-rc1 have explosions? |
(The PEP8 error appears spurious and unrelated to this PR) |
Changes in synapse v0.27.0-rc2 (2018-03-19) =========================================== Pulls in v0.26.1 Bug fixes: * Fix bug introduced in v0.27.0-rc1 that causes much increased memory usage in state cache (PR matrix-org#3005) Changes in synapse v0.26.1 (2018-03-15) ======================================= Bug fixes: * Fix bug where an invalid event caused server to stop functioning correctly, due to parsing and serializing bugs in ujson library (PR matrix-org#3008)
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.