diff --git a/synapse/push/bulk_push_rule_evaluator.py b/synapse/push/bulk_push_rule_evaluator.py index 1d32760a7bcf..2409c6f5ba7f 100644 --- a/synapse/push/bulk_push_rule_evaluator.py +++ b/synapse/push/bulk_push_rule_evaluator.py @@ -267,6 +267,10 @@ async def action_for_event_by_user( room_members = await self.store.get_joined_users_from_context(event, context) + room_member_count = await self.store.get_number_joined_users_in_room( + event.room_id + ) + ( power_levels, sender_power_level, @@ -278,7 +282,7 @@ async def action_for_event_by_user( evaluator = PushRuleEvaluatorForEvent( event, - len(room_members), + room_member_count, sender_power_level, power_levels, relations, diff --git a/synapse/storage/_base.py b/synapse/storage/_base.py index abfc56b0616c..177b9a90c5aa 100644 --- a/synapse/storage/_base.py +++ b/synapse/storage/_base.py @@ -75,6 +75,9 @@ def _invalidate_state_caches( self._attempt_to_invalidate_cache( "get_users_in_room_with_profiles", (room_id,) ) + self._attempt_to_invalidate_cache( + "get_number_joined_users_in_room.invalidate", (room_id,) + ) # Purge other caches based on room state. self._attempt_to_invalidate_cache("get_room_summary", (room_id,)) diff --git a/synapse/storage/databases/main/cache.py b/synapse/storage/databases/main/cache.py index a07d48f66c95..17f7bf66bf1b 100644 --- a/synapse/storage/databases/main/cache.py +++ b/synapse/storage/databases/main/cache.py @@ -218,6 +218,7 @@ def _invalidate_caches_for_event( self._membership_stream_cache.entity_has_changed(state_key, stream_ordering) self.get_invited_rooms_for_local_user.invalidate((state_key,)) self.get_local_users_in_room.invalidate((room_id,)) + self.get_number_joined_users_in_room((room_id,)) if relates_to: self.get_relations_for_event.invalidate((relates_to,)) diff --git a/synapse/storage/databases/main/events.py b/synapse/storage/databases/main/events.py index 46a004ce7985..5787f4fc559d 100644 --- a/synapse/storage/databases/main/events.py +++ b/synapse/storage/databases/main/events.py @@ -1770,6 +1770,10 @@ def _store_room_members_txn( self.store.get_local_users_in_room.invalidate, (event.room_id,), ) + txn.call_after( + self.store.get_number_joined_users_in_room.invalidate, + (event.room_id,), + ) # The `_get_membership_from_event_id` is immutable, except for the # case where we look up an event *before* persisting it. diff --git a/synapse/storage/databases/main/roommember.py b/synapse/storage/databases/main/roommember.py index ac6f568e6852..9bb83ac8ac75 100644 --- a/synapse/storage/databases/main/roommember.py +++ b/synapse/storage/databases/main/roommember.py @@ -337,6 +337,15 @@ def _get_room_summary_txn( "get_room_summary", _get_room_summary_txn ) + @cached() + async def get_number_joined_users_in_room(self, room_id: str) -> int: + return await self.db_pool.simple_select_one_onecol( + table="current_state_events", + keyvalues={"room_id": room_id, "membership": Membership.JOIN}, + retcol="COUNT(*)", + desc="get_number_joined_users_in_room", + ) + @cached() async def get_invited_rooms_for_local_user( self, user_id: str