Improve performance of is_server_admin by adding a cache (#18747)

Fixes https://github.com/element-hq/synapse/issues/18738
This commit is contained in:
Andrew Morgan
2025-07-30 11:43:39 +01:00
committed by GitHub
parent 61e79a4cdf
commit 7ae7468159
3 changed files with 10 additions and 5 deletions

1
changelog.d/18747.misc Normal file
View File

@@ -0,0 +1 @@
Fix performance regression introduced in #18238 by adding a cache to `is_server_admin`.

View File

@@ -673,6 +673,7 @@ class RegistrationWorkerStore(StatsStore, CacheInvalidationWorkerStore):
desc="delete_account_validity_for_user",
)
@cached(max_entries=100000)
async def is_server_admin(self, user: UserID) -> bool:
"""Determines if a user is an admin of this homeserver.
@@ -707,6 +708,9 @@ class RegistrationWorkerStore(StatsStore, CacheInvalidationWorkerStore):
self._invalidate_cache_and_stream(
txn, self.get_user_by_id, (user.to_string(),)
)
self._invalidate_cache_and_stream(
txn, self.is_server_admin, (user.to_string(),)
)
await self.db_pool.runInteraction("set_server_admin", set_server_admin_txn)

View File

@@ -1181,7 +1181,7 @@ class BundledAggregationsTestCase(BaseRelationsTestCase):
bundled_aggregations,
)
self._test_bundled_aggregations(RelationTypes.REFERENCE, assert_annotations, 8)
self._test_bundled_aggregations(RelationTypes.REFERENCE, assert_annotations, 7)
def test_thread(self) -> None:
"""
@@ -1226,21 +1226,21 @@ class BundledAggregationsTestCase(BaseRelationsTestCase):
# The "user" sent the root event and is making queries for the bundled
# aggregations: they have participated.
self._test_bundled_aggregations(RelationTypes.THREAD, _gen_assert(True), 9)
self._test_bundled_aggregations(RelationTypes.THREAD, _gen_assert(True), 7)
# The "user2" sent replies in the thread and is making queries for the
# bundled aggregations: they have participated.
#
# Note that this re-uses some cached values, so the total number of
# queries is much smaller.
self._test_bundled_aggregations(
RelationTypes.THREAD, _gen_assert(True), 6, access_token=self.user2_token
RelationTypes.THREAD, _gen_assert(True), 4, access_token=self.user2_token
)
# A user with no interactions with the thread: they have not participated.
user3_id, user3_token = self._create_user("charlie")
self.helper.join(self.room, user=user3_id, tok=user3_token)
self._test_bundled_aggregations(
RelationTypes.THREAD, _gen_assert(False), 6, access_token=user3_token
RelationTypes.THREAD, _gen_assert(False), 4, access_token=user3_token
)
def test_thread_with_bundled_aggregations_for_latest(self) -> None:
@@ -1287,7 +1287,7 @@ class BundledAggregationsTestCase(BaseRelationsTestCase):
bundled_aggregations["latest_event"].get("unsigned"),
)
self._test_bundled_aggregations(RelationTypes.THREAD, assert_thread, 9)
self._test_bundled_aggregations(RelationTypes.THREAD, assert_thread, 7)
def test_nested_thread(self) -> None:
"""