diff --git a/synapse/push/bulk_push_rule_evaluator.py b/synapse/push/bulk_push_rule_evaluator.py
index 90436a043e..6b7aa6b74d 100644
--- a/synapse/push/bulk_push_rule_evaluator.py
+++ b/synapse/push/bulk_push_rule_evaluator.py
@@ -211,13 +211,17 @@ class BulkPushRuleEvaluator:
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,
) = await self._get_power_levels_and_sender_level(event, context)
evaluator = PushRuleEvaluatorForEvent(
- event, len(room_members), sender_power_level, power_levels
+ event, room_member_count, sender_power_level, power_levels
)
# If the event is not a state event check if any users ignore the sender.
diff --git a/synapse/storage/_base.py b/synapse/storage/_base.py
index 8df80664a2..f2a40b9308 100644
--- a/synapse/storage/_base.py
+++ b/synapse/storage/_base.py
@@ -74,6 +74,9 @@ class SQLBaseStore(metaclass=ABCMeta):
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 a07d48f66c..17f7bf66bf 100644
--- a/synapse/storage/databases/main/cache.py
+++ b/synapse/storage/databases/main/cache.py
@@ -218,6 +218,7 @@ class CacheInvalidationWorkerStore(SQLBaseStore):
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 28190bf6f5..b533b944bc 100644
--- a/synapse/storage/databases/main/events.py
+++ b/synapse/storage/databases/main/events.py
@@ -1770,6 +1770,10 @@ class PersistEventsStore:
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 70a30e75b0..72202b1373 100644
--- a/synapse/storage/databases/main/roommember.py
+++ b/synapse/storage/databases/main/roommember.py
@@ -338,6 +338,15 @@ class RoomMemberWorkerStore(EventsWorkerStore):
)
@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
) -> List[RoomsForUser]:
|