diff --git a/synapse/__init__.py b/synapse/__init__.py
index 6327147d8e..5e957985d7 100644
--- a/synapse/__init__.py
+++ b/synapse/__init__.py
@@ -36,7 +36,7 @@ try:
except ImportError:
pass
-__version__ = "1.14.0rc1"
+__version__ = "1.14.0rc2"
if bool(os.environ.get("SYNAPSE_TEST_PATCH_LOG_CONTEXTS", False)):
# We import here so that we don't have to install a bunch of deps when
diff --git a/synapse/config/cache.py b/synapse/config/cache.py
index 91036a012e..0672538796 100644
--- a/synapse/config/cache.py
+++ b/synapse/config/cache.py
@@ -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"
@@ -37,6 +41,20 @@ class CacheProperties(object):
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 denote 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
@@ -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
#
@@ -105,6 +126,12 @@ class CacheConfig(Config):
# takes priority over setting through the config file.
# Ex. SYNAPSE_CACHE_FACTOR_GET_USERS_WHO_SHARE_ROOM_WITH_USER=2.0
#
+ # Some caches have '*' and other characters that are not
+ # alphanumeric or underscores. These caches can be named with or
+ # without the special characters stripped. For example, to specify
+ # the cache factor for `*stateGroupCache*` via an environment
+ # variable would be `SYNAPSE_CACHE_FACTOR_STATEGROUPCACHE=2.0`.
+ #
per_cache_factors:
#get_users_who_share_room_with_user: 2.0
"""
@@ -130,10 +157,17 @@ class CacheConfig(Config):
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 + "_")
}
@@ -142,9 +176,9 @@ class CacheConfig(Config):
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()
diff --git a/synapse/config/oidc_config.py b/synapse/config/oidc_config.py
index 5af110745e..586038078f 100644
--- a/synapse/config/oidc_config.py
+++ b/synapse/config/oidc_config.py
@@ -112,7 +112,7 @@ class OIDCConfig(Config):
# auth method to use when exchanging the token.
# Valid values are "client_secret_basic" (default), "client_secret_post" and "none".
#
- #client_auth_method: "client_auth_basic"
+ #client_auth_method: "client_secret_basic"
# list of scopes to ask. This should include the "openid" scope. Defaults to ["openid"].
#
diff --git a/synapse/replication/tcp/handler.py b/synapse/replication/tcp/handler.py
index 03300e5336..cbcf46f3ae 100644
--- a/synapse/replication/tcp/handler.py
+++ b/synapse/replication/tcp/handler.py
@@ -159,6 +159,9 @@ class ReplicationCommandHandler:
hs.config.redis_port,
)
+ # First let's ensure that we have a ReplicationStreamer started.
+ hs.get_replication_streamer()
+
# We need two connections to redis, one for the subscription stream and
# one to send commands to (as you can't send further redis commands to a
# connection after SUBSCRIBE is called).
diff --git a/synapse/util/caches/lrucache.py b/synapse/util/caches/lrucache.py
index 29fabac3cd..df4ea5901d 100644
--- a/synapse/util/caches/lrucache.py
+++ b/synapse/util/caches/lrucache.py
@@ -81,6 +81,7 @@ class LruCache(object):
"""
cache = cache_type()
self.cache = cache # Used for introspection.
+ self.apply_cache_factor_from_config = apply_cache_factor_from_config
# Save the original max size, and apply the default size factor.
self._original_max_size = max_size
@@ -294,6 +295,9 @@ class LruCache(object):
Returns:
bool: Whether the cache changed size or not.
"""
+ if not self.apply_cache_factor_from_config:
+ return False
+
new_size = int(self._original_max_size * factor)
if new_size != self.max_size:
self.max_size = new_size
|