Try to update to support per-user enablement

This commit is contained in:
Will Hunt
2025-11-11 16:04:56 +00:00
parent 3eb0e781d8
commit b3a49eac79
8 changed files with 38 additions and 32 deletions

View File

@@ -595,4 +595,4 @@ class ExperimentalConfig(Config):
self.msc4306_enabled: bool = experimental.get("msc4306_enabled", False)
# MSC4354: Sticky Events
self.msc4354_enabled: bool = experimental.get("msc4354_enabled", False)
self.msc4354_enabled_value: bool = experimental.get("msc4354_enabled", False)

View File

@@ -511,8 +511,6 @@ class FederationSender(AbstractFederationSender):
def notify_new_server_joined(self, server: str, room_id: str) -> None:
# We currently only use this notification for MSC4354: Sticky Events.
if not self.hs.config.experimental.msc4354_enabled:
return
# fire off a processing loop in the background
self.hs.run_as_background_process(
"process_new_server_joined_over_federation",

View File

@@ -104,7 +104,6 @@ class PerDestinationQueue:
self._instance_name = hs.get_instance_name()
self._federation_shard_config = hs.config.worker.federation_shard_config
self._state = hs.get_state_handler()
self.msc4354_enabled = hs.config.experimental.msc4354_enabled
self._should_send_on_this_instance = True
if not self._federation_shard_config.should_handle(
@@ -582,7 +581,6 @@ class PerDestinationQueue:
# send.
extrem_events = await self._store.get_events_as_list(extrems)
if self.msc4354_enabled:
# we also want to send sticky events that are still active in this room
sticky_event_ids = (
await self._store.get_sticky_event_ids_sent_by_self(

View File

@@ -82,6 +82,7 @@ from synapse.util.caches.lrucache import LruCache
from synapse.util.caches.response_cache import ResponseCache, ResponseCacheContext
from synapse.util.metrics import Measure
from synapse.visibility import filter_events_for_client
from synapse.rest.admin.experimental_features import ExperimentalFeature
if TYPE_CHECKING:
from synapse.server import HomeServer
@@ -2178,6 +2179,7 @@ class SyncHandler:
since_token = sync_result_builder.since_token
user_id = sync_result_builder.sync_config.user.to_string()
calculate_sticky_events = self.store.is_feature_enabled(user_id, ExperimentalFeature.MSC4354)
blocks_all_rooms = (
sync_result_builder.sync_config.filter_collection.blocks_all_rooms()
@@ -2216,7 +2218,7 @@ class SyncHandler:
sync_result_builder.now_token = now_token
sticky_by_room: Dict[str, Set[str]] = {}
if self.hs_config.experimental.msc4354_enabled:
if await calculate_sticky_events:
now_token, sticky_by_room = await self.sticky_events_by_room(
sync_result_builder, now_token, since_token
)

View File

@@ -44,6 +44,7 @@ class ExperimentalFeature(str, Enum):
MSC3881 = "msc3881"
MSC3575 = "msc3575"
MSC4222 = "msc4222"
MSC4354 = "msc4354"
def is_globally_enabled(self, config: "HomeServerConfig") -> bool:
if self is ExperimentalFeature.MSC3881:
@@ -52,6 +53,8 @@ class ExperimentalFeature(str, Enum):
return config.experimental.msc3575_enabled
if self is ExperimentalFeature.MSC4222:
return config.experimental.msc4222_enabled
if self is ExperimentalFeature.MSC4354:
return config.experimental.msc4354_enabled
assert_never(self)

View File

@@ -81,6 +81,9 @@ class VersionsRestServlet(RestServlet):
msc3575_enabled = await self.store.is_feature_enabled(
user_id, ExperimentalFeature.MSC3575
)
msc4354_enabled = await self.store.is_feature_enabled(
user_id, ExperimentalFeature.MSC4354
)
return (
200,
@@ -183,7 +186,7 @@ class VersionsRestServlet(RestServlet):
# MSC4169: Backwards-compatible redaction sending using `/send`
"com.beeper.msc4169": self.config.experimental.msc4169_enabled,
# MSC4354: Sticky events
"org.matrix.msc4354": self.config.experimental.msc4354_enabled,
"org.matrix.msc4354": msc4354_enabled,
},
},
)

View File

@@ -114,7 +114,7 @@ class ExperimentalFeaturesStore(CacheInvalidationWorkerStore):
if feature.is_globally_enabled(self.hs.config):
return True
msc4354_enabled
# if it's not enabled globally, check if it is enabled per-user
res = await self.db_pool.simple_select_one_onecol(
table="per_user_experimental_features",

View File

@@ -50,6 +50,7 @@ from synapse.types import (
)
from synapse.types.state import StateFilter
from synapse.util.clock import Clock
from synapse.rest.admin.experimental_features import ExperimentalFeature
logger = logging.getLogger(__name__)
filtered_event_logger = logging.getLogger("synapse.visibility.filtered_event_debug")
@@ -110,6 +111,7 @@ async def filter_events_for_client(
# We copy the events list to guarantee any modifications we make will only
# happen within the function.
events_before_filtering = events.copy()
sticky_events_enabled = await storage.main.is_feature_enabled(user_id, ExperimentalFeature.MSC4354)
# Default case is to *exclude* soft-failed events
events = [e for e in events if not e.internal_metadata.is_soft_failed()]
client_config = await storage.main.get_admin_client_config_for_user(user_id)
@@ -203,7 +205,7 @@ async def filter_events_for_client(
# to the cache!
cloned = clone_event(filtered)
cloned.unsigned[EventUnsignedContentFields.MEMBERSHIP] = user_membership
if storage.main.config.experimental.msc4354_enabled:
if sticky_events_enabled:
sticky_duration = cloned.sticky_duration()
if sticky_duration:
now = storage.main.clock.time_msec()