Quellcode durchsuchen

Fix 'LruCache' object has no attribute '_on_resize' (#8591)

We need to make sure we are readu for the `set_cache_factor` callback.
Richard van der Hoff vor 3 Jahren
Ursprung
Commit
96e7d3c4a0
3 geänderte Dateien mit 17 neuen und 2 gelöschten Zeilen
  1. 1 0
      changelog.d/8591.misc
  2. 9 1
      synapse/util/caches/lrucache.py
  3. 7 1
      tests/util/test_lrucache.py

+ 1 - 0
changelog.d/8591.misc

@@ -0,0 +1 @@
+ Move metric registration code down into `LruCache`.

+ 9 - 1
synapse/util/caches/lrucache.py

@@ -124,6 +124,10 @@ class LruCache(Generic[KT, VT]):
         else:
             self.max_size = int(max_size)
 
+        # register_cache might call our "set_cache_factor" callback; there's nothing to
+        # do yet when we get resized.
+        self._on_resize = None  # type: Optional[Callable[[],None]]
+
         if cache_name is not None:
             metrics = register_cache(
                 "lru_cache",
@@ -332,7 +336,10 @@ class LruCache(Generic[KT, VT]):
             return key in cache
 
         self.sentinel = object()
+
+        # make sure that we clear out any excess entries after we get resized.
         self._on_resize = evict
+
         self.get = cache_get
         self.set = cache_set
         self.setdefault = cache_set_default
@@ -383,6 +390,7 @@ class LruCache(Generic[KT, VT]):
         new_size = int(self._original_max_size * factor)
         if new_size != self.max_size:
             self.max_size = new_size
-            self._on_resize()
+            if self._on_resize:
+                self._on_resize()
             return True
         return False

+ 7 - 1
tests/util/test_lrucache.py

@@ -19,7 +19,8 @@ from mock import Mock
 from synapse.util.caches.lrucache import LruCache
 from synapse.util.caches.treecache import TreeCache
 
-from .. import unittest
+from tests import unittest
+from tests.unittest import override_config
 
 
 class LruCacheTestCase(unittest.HomeserverTestCase):
@@ -83,6 +84,11 @@ class LruCacheTestCase(unittest.HomeserverTestCase):
         cache.clear()
         self.assertEquals(len(cache), 0)
 
+    @override_config({"caches": {"per_cache_factors": {"mycache": 10}}})
+    def test_special_size(self):
+        cache = LruCache(10, "mycache")
+        self.assertEqual(cache.max_size, 100)
+
 
 class LruCacheCallbacksTestCase(unittest.HomeserverTestCase):
     def test_get(self):