mirror of
				https://github.com/matrix-org/synapse.git
				synced 2025-11-04 10:11:05 +01:00 
			
		
		
		
	Merge pull request #3005 from matrix-org/erikj/fix_cache_size
Fix bug where state cache used lots of memory
This commit is contained in:
		
						commit
						3f961e638a
					
				@ -132,9 +132,13 @@ class DictionaryCache(object):
 | 
				
			|||||||
                self._update_or_insert(key, value, known_absent)
 | 
					                self._update_or_insert(key, value, known_absent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _update_or_insert(self, 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.value.update(value)
 | 
				
			||||||
        entry.known_absent.update(known_absent)
 | 
					        entry.known_absent.update(known_absent)
 | 
				
			||||||
 | 
					        self.cache[key] = entry
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _insert(self, key, value, known_absent):
 | 
					    def _insert(self, key, value, known_absent):
 | 
				
			||||||
        self.cache[key] = DictionaryEntry(True, known_absent, value)
 | 
					        self.cache[key] = DictionaryEntry(True, known_absent, value)
 | 
				
			||||||
 | 
				
			|||||||
@ -154,14 +154,21 @@ class LruCache(object):
 | 
				
			|||||||
        def cache_set(key, value, callbacks=[]):
 | 
					        def cache_set(key, value, callbacks=[]):
 | 
				
			||||||
            node = cache.get(key, None)
 | 
					            node = cache.get(key, None)
 | 
				
			||||||
            if node is not None:
 | 
					            if node is not None:
 | 
				
			||||||
                if value != node.value:
 | 
					                # We sometimes store large objects, e.g. dicts, which cause
 | 
				
			||||||
 | 
					                # the inequality check to take a long time. So let's only do
 | 
				
			||||||
 | 
					                # the check if we have some callbacks to call.
 | 
				
			||||||
 | 
					                if node.callbacks and value != node.value:
 | 
				
			||||||
                    for cb in node.callbacks:
 | 
					                    for cb in node.callbacks:
 | 
				
			||||||
                        cb()
 | 
					                        cb()
 | 
				
			||||||
                    node.callbacks.clear()
 | 
					                    node.callbacks.clear()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if size_callback:
 | 
					                # We don't bother to protect this by value != node.value as
 | 
				
			||||||
                        cached_cache_len[0] -= size_callback(node.value)
 | 
					                # generally size_callback will be cheap compared with equality
 | 
				
			||||||
                        cached_cache_len[0] += size_callback(value)
 | 
					                # checks. (For example, taking the size of two dicts is quicker
 | 
				
			||||||
 | 
					                # than comparing them for equality.)
 | 
				
			||||||
 | 
					                if size_callback:
 | 
				
			||||||
 | 
					                    cached_cache_len[0] -= size_callback(node.value)
 | 
				
			||||||
 | 
					                    cached_cache_len[0] += size_callback(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                node.callbacks.update(callbacks)
 | 
					                node.callbacks.update(callbacks)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user