Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 1008106

Browse files
committed
Reimplement get_rooms_for_user and get_rooms_for_users
This avoids the join on `events` to get stream ordering that is mostly unused.
1 parent fa2f3d8 commit 1008106

File tree

3 files changed

+79
-7
lines changed

3 files changed

+79
-7
lines changed

synapse/storage/databases/main/cache.py

+3
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ def _process_event_stream_row(self, token: int, row: EventsStreamRow) -> None:
205205
self.get_rooms_for_user_with_stream_ordering.invalidate(
206206
(data.state_key,)
207207
)
208+
self.get_rooms_for_user.invalidate(
209+
(data.state_key,)
210+
)
208211
else:
209212
raise Exception("Unknown events stream row type %s" % (row.type,))
210213

synapse/storage/databases/main/events.py

+4
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,10 @@ def _update_current_state_txn(
11781178
self.store.get_rooms_for_user_with_stream_ordering.invalidate,
11791179
(member,),
11801180
)
1181+
txn.call_after(
1182+
self.store.get_rooms_for_user.invalidate,
1183+
(member,),
1184+
)
11811185

11821186
self.store._invalidate_state_caches_and_stream(
11831187
txn, room_id, members_changed

synapse/storage/databases/main/roommember.py

+72-7
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import logging
1616
from typing import (
1717
TYPE_CHECKING,
18-
Callable,
1918
Collection,
2019
Dict,
2120
FrozenSet,
@@ -52,7 +51,6 @@
5251
from synapse.util.async_helpers import Linearizer
5352
from synapse.util.caches import intern_string
5453
from synapse.util.caches.descriptors import _CacheContext, cached, cachedList
55-
from synapse.util.cancellation import cancellable
5654
from synapse.util.iterutils import batch_iter
5755
from synapse.util.metrics import Measure
5856

@@ -670,19 +668,86 @@ def _get_users_server_still_shares_room_with_txn(
670668
_get_users_server_still_shares_room_with_txn,
671669
)
672670

673-
@cancellable
671+
@cached(max_entries=500000, iterable=True)
674672
async def get_rooms_for_user(
675-
self, user_id: str, on_invalidate: Optional[Callable[[], None]] = None
673+
self, user_id: str
676674
) -> FrozenSet[str]:
677675
"""Returns a set of room_ids the user is currently joined to.
678676
679677
If a remote user only returns rooms this server is currently
680678
participating in.
681679
"""
682-
rooms = await self.get_rooms_for_user_with_stream_ordering(
683-
user_id, on_invalidate=on_invalidate
680+
rooms = self.get_rooms_for_user_with_stream_ordering.cache.get_immediate(user_id)
681+
if rooms:
682+
return frozenset(r.room_id for r in rooms)
683+
684+
return await self.db_pool.runInteraction(
685+
"get_rooms_for_user",
686+
self._get_rooms_for_user_txn,
687+
user_id,
684688
)
685-
return frozenset(r.room_id for r in rooms)
689+
690+
def _get_rooms_for_user_txn(
691+
self, txn: LoggingTransaction, user_id: str
692+
) -> FrozenSet[str]:
693+
sql = """
694+
SELECT room_id
695+
FROM current_state_events AS c
696+
WHERE
697+
c.type = 'm.room.member'
698+
AND c.state_key = ?
699+
AND c.membership = ?
700+
"""
701+
702+
txn.execute(sql, (user_id, Membership.JOIN))
703+
return frozenset(txn)
704+
705+
@cachedList(
706+
cached_method_name="get_rooms_for_user",
707+
list_name="user_ids",
708+
)
709+
async def get_rooms_for_users(
710+
self, user_ids: Collection[str]
711+
) -> Dict[str, FrozenSet[GetRoomsForUserWithStreamOrdering]]:
712+
"""A batched version of `get_rooms_for_user`.
713+
714+
Returns:
715+
Map from user_id to set of rooms that is currently in.
716+
"""
717+
return await self.db_pool.runInteraction(
718+
"get_rooms_for_users",
719+
self._get_rooms_for_users_txn,
720+
user_ids,
721+
)
722+
723+
def _get_rooms_for_users_txn(
724+
self, txn: LoggingTransaction, user_ids: Collection[str]
725+
) -> Dict[str, FrozenSet[str]]:
726+
727+
clause, args = make_in_list_sql_clause(
728+
self.database_engine,
729+
"c.state_key",
730+
user_ids,
731+
)
732+
733+
sql = f"""
734+
SELECT c.state_key, room_id
735+
FROM current_state_events AS c
736+
WHERE
737+
c.type = 'm.room.member'
738+
AND c.membership = ?
739+
AND {clause}
740+
"""
741+
742+
txn.execute(sql, [Membership.JOIN] + args)
743+
744+
result: Dict[str, Set[str]] = {
745+
user_id: set() for user_id in user_ids
746+
}
747+
for user_id, room_id in txn:
748+
result[user_id].add(room_id)
749+
750+
return {user_id: frozenset(v) for user_id, v in result.items()}
686751

687752
@cached(max_entries=10000)
688753
async def does_pair_of_users_share_a_room(

0 commit comments

Comments
 (0)