Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Fix specifying cache factors via env vars with * in name.
Browse files Browse the repository at this point in the history
This mostly applise to `*stateGroupCache*` and co.

Broke in #6391.
  • Loading branch information
erikjohnston committed May 27, 2020
1 parent 651bb76 commit 7d188fc
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 5 deletions.
38 changes: 33 additions & 5 deletions synapse/config/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@
# limitations under the License.

import os
import re
from typing import Callable, Dict

from ._base import Config, ConfigError

# The prefix for all cache factor-related environment variables
_CACHES = {}
_CACHE_PREFIX = "SYNAPSE_CACHE_FACTOR"

# Map from canonicalised cache name to cache.
_CACHES = {}

_DEFAULT_FACTOR_SIZE = 0.5
_DEFAULT_EVENT_CACHE_SIZE = "10K"

Expand All @@ -37,6 +41,20 @@ def __init__(self):
properties = CacheProperties()


def _canonicalise_cache_name(cache_name: str) -> str:
"""Gets the canonical form of the cache name.
Since we specify cache names in config and environment variables we need to
ignore case and special characters. For example, some caches have asterisks
in their name to donate that they're not attached to a particular database
function, and these asterisks need to be stripped out
"""

cache_name = re.sub(r"[^A-Za-z_1-9]", "", cache_name)

return cache_name.lower()


def add_resizable_cache(cache_name: str, cache_resize_callback: Callable):
"""Register a cache that's size can dynamically change
Expand All @@ -45,7 +63,10 @@ def add_resizable_cache(cache_name: str, cache_resize_callback: Callable):
cache_resize_callback: A callback function that will be ran whenever
the cache needs to be resized
"""
_CACHES[cache_name.lower()] = cache_resize_callback
# Some caches have '*' in them which we strip out.
cache_name = _canonicalise_cache_name(cache_name)

_CACHES[cache_name] = cache_resize_callback

# Ensure all loaded caches are sized appropriately
#
Expand Down Expand Up @@ -130,10 +151,17 @@ def read_config(self, config, **kwargs):
if not isinstance(individual_factors, dict):
raise ConfigError("caches.per_cache_factors must be a dictionary")

# Canonicalise the cache names *before* updating with the environment
# variables.
individual_factors = {
_canonicalise_cache_name(key): val
for key, val in individual_factors.items()
}

# Override factors from environment if necessary
individual_factors.update(
{
key[len(_CACHE_PREFIX) + 1 :].lower(): float(val)
_canonicalise_cache_name(key[len(_CACHE_PREFIX) + 1 :]): float(val)
for key, val in self._environ.items()
if key.startswith(_CACHE_PREFIX + "_")
}
Expand All @@ -142,9 +170,9 @@ def read_config(self, config, **kwargs):
for cache, factor in individual_factors.items():
if not isinstance(factor, (int, float)):
raise ConfigError(
"caches.per_cache_factors.%s must be a number" % (cache.lower(),)
"caches.per_cache_factors.%s must be a number" % (cache,)
)
self.cache_factors[cache.lower()] = factor
self.cache_factors[cache] = factor

# Resize all caches (if necessary) with the new factors we've loaded
self.resize_all_caches()
Expand Down
28 changes: 28 additions & 0 deletions tests/config/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,31 @@ def test_global_instantiated_after_config_load(self):
cache = LruCache(100)
add_resizable_cache("foo", cache_resize_callback=cache.set_cache_factor)
self.assertEqual(cache.max_size, 150)

def test_cache_with_asterisk_in_name(self):
"""Some caches have asterisks in their name, test that they are set correctly.
"""

config = {
"caches": {
"per_cache_factors": {"*cache_a*": 5, "cache_b": 6, "cache_c": 2}
}
}
t = TestConfig()
t.caches._environ = {
"SYNAPSE_CACHE_FACTOR_CACHE_A": "2",
"SYNAPSE_CACHE_FACTOR_CACHE_B": 3,
}
t.read_config(config, config_dir_path="", data_dir_path="")

cache_a = LruCache(100)
add_resizable_cache("*cache_a*", cache_resize_callback=cache_a.set_cache_factor)
self.assertEqual(cache_a.max_size, 200)

cache_b = LruCache(100)
add_resizable_cache("*Cache_b*", cache_resize_callback=cache_b.set_cache_factor)
self.assertEqual(cache_b.max_size, 300)

cache_c = LruCache(100)
add_resizable_cache("*cache_c*", cache_resize_callback=cache_c.set_cache_factor)
self.assertEqual(cache_c.max_size, 200)

0 comments on commit 7d188fc

Please sign in to comment.