Skip to content

Commit

Permalink
Add a cache on get_rooms_for_local_user_where_membership_is
Browse files Browse the repository at this point in the history
  • Loading branch information
erikjohnston committed Jul 19, 2024
1 parent 43c865f commit 7ef8f88
Show file tree
Hide file tree
Showing 10 changed files with 41 additions and 12 deletions.
2 changes: 1 addition & 1 deletion synapse/api/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Membership:
KNOCK: Final = "knock"
LEAVE: Final = "leave"
BAN: Final = "ban"
LIST: Final = {INVITE, JOIN, KNOCK, LEAVE, BAN}
LIST: Final = (INVITE, JOIN, KNOCK, LEAVE, BAN)


class PresenceState:
Expand Down
2 changes: 1 addition & 1 deletion synapse/handlers/initial_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ async def _snapshot_all_rooms(
memberships.append(Membership.LEAVE)

room_list = await self.store.get_rooms_for_local_user_where_membership_is(
user_id=user_id, membership_list=memberships
user_id=user_id, membership_list=tuple(memberships)
)

user = UserID.from_string(user_id)
Expand Down
2 changes: 1 addition & 1 deletion synapse/handlers/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ async def _search(
# TODO: Search through left rooms too
rooms = await self.store.get_rooms_for_local_user_where_membership_is(
requester.user.to_string(),
membership_list=[Membership.JOIN],
membership_list=(Membership.JOIN,),
# membership_list=[Membership.JOIN, Membership.LEAVE, Membership.Ban],
)
room_ids = {r.room_id for r in rooms}
Expand Down
4 changes: 2 additions & 2 deletions synapse/server_notices/server_notices_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ async def maybe_get_notice_room_for_user(self, user_id: str) -> Optional[str]:
return None

rooms = await self._store.get_rooms_for_local_user_where_membership_is(
user_id, [Membership.INVITE, Membership.JOIN]
user_id, (Membership.INVITE, Membership.JOIN)
)
for room in rooms:
# it's worth noting that there is an asymmetry here in that we
Expand Down Expand Up @@ -262,7 +262,7 @@ async def maybe_invite_user_to_room(self, user_id: str, room_id: str) -> None:
# Check whether the user has already joined or been invited to this room. If
# that's the case, there is no need to re-invite them.
joined_rooms = await self._store.get_rooms_for_local_user_where_membership_is(
user_id, [Membership.INVITE, Membership.JOIN]
user_id, (Membership.INVITE, Membership.JOIN)
)
for room in joined_rooms:
if room.room_id == room_id:
Expand Down
6 changes: 6 additions & 0 deletions synapse/storage/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ def _invalidate_state_caches(
"get_user_in_room_with_profile", (room_id, user_id)
)
self._attempt_to_invalidate_cache("get_rooms_for_user", (user_id,))
self._attempt_to_invalidate_cache(
"_get_rooms_for_local_user_where_membership_is_inner", (user_id,)
)

# Purge other caches based on room state.
self._attempt_to_invalidate_cache("get_room_summary", (room_id,))
Expand All @@ -146,6 +149,9 @@ def _invalidate_state_caches_all(self, room_id: str) -> None:
self._attempt_to_invalidate_cache("does_pair_of_users_share_a_room", None)
self._attempt_to_invalidate_cache("get_user_in_room_with_profile", None)
self._attempt_to_invalidate_cache("get_rooms_for_user", None)
self._attempt_to_invalidate_cache(
"_get_rooms_for_local_user_where_membership_is_inner", None
)
self._attempt_to_invalidate_cache("get_room_summary", (room_id,))

def _attempt_to_invalidate_cache(
Expand Down
6 changes: 6 additions & 0 deletions synapse/storage/databases/main/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,9 @@ def _invalidate_caches_for_event(
"get_invited_rooms_for_local_user", (state_key,)
)
self._attempt_to_invalidate_cache("get_rooms_for_user", (state_key,))
self._attempt_to_invalidate_cache(
"_get_rooms_for_local_user_where_membership_is_inner", (state_key,)
)

self._attempt_to_invalidate_cache(
"did_forget",
Expand Down Expand Up @@ -393,6 +396,9 @@ def _invalidate_caches_for_room_events(self, room_id: str) -> None:
self._attempt_to_invalidate_cache("get_thread_id_for_receipts", None)
self._attempt_to_invalidate_cache("get_invited_rooms_for_local_user", None)
self._attempt_to_invalidate_cache("get_rooms_for_user", None)
self._attempt_to_invalidate_cache(
"_get_rooms_for_local_user_where_membership_is_inner", None
)
self._attempt_to_invalidate_cache("did_forget", None)
self._attempt_to_invalidate_cache("get_forgotten_rooms_for_user", None)
self._attempt_to_invalidate_cache("get_references_for_event", None)
Expand Down
26 changes: 21 additions & 5 deletions synapse/storage/databases/main/roommember.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ async def get_invited_rooms_for_local_user(
"""

return await self.get_rooms_for_local_user_where_membership_is(
user_id, [Membership.INVITE]
user_id, (Membership.INVITE,)
)

async def get_knocked_at_rooms_for_local_user(
Expand All @@ -401,7 +401,7 @@ async def get_knocked_at_rooms_for_local_user(
"""

return await self.get_rooms_for_local_user_where_membership_is(
user_id, [Membership.KNOCK]
user_id, (Membership.KNOCK,)
)

async def get_invite_for_local_user_in_room(
Expand Down Expand Up @@ -445,9 +445,7 @@ async def get_rooms_for_local_user_where_membership_is(
if not membership_list:
return []

rooms = await self.db_pool.runInteraction(
"get_rooms_for_local_user_where_membership_is",
self._get_rooms_for_local_user_where_membership_is_txn,
rooms = await self._get_rooms_for_local_user_where_membership_is_inner(
user_id,
membership_list,
)
Expand All @@ -466,6 +464,24 @@ async def get_rooms_for_local_user_where_membership_is(

return [room for room in rooms if room.room_id not in rooms_to_exclude]

@cached(max_entries=1000, tree=True)
async def _get_rooms_for_local_user_where_membership_is_inner(
self,
user_id: str,
membership_list: Collection[str],
) -> Sequence[RoomsForUser]:
if not membership_list:
return []

rooms = await self.db_pool.runInteraction(
"get_rooms_for_local_user_where_membership_is",
self._get_rooms_for_local_user_where_membership_is_txn,
user_id,
membership_list,
)

return rooms

def _get_rooms_for_local_user_where_membership_is_txn(
self,
txn: LoggingTransaction,
Expand Down
1 change: 1 addition & 0 deletions tests/handlers/test_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ def test_unknown_room_version(self) -> None:

# Blow away caches (supported room versions can only change due to a restart).
self.store.get_rooms_for_user.invalidate_all()
self.store._get_rooms_for_local_user_where_membership_is_inner.invalidate_all()
self.store._get_event_cache.clear()
self.store._event_ref.clear()

Expand Down
2 changes: 1 addition & 1 deletion tests/rest/client/test_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ def test_pending_invites(self) -> None:
# Check that the membership of @invitee:test in the room is now "leave".
memberships = self.get_success(
store.get_rooms_for_local_user_where_membership_is(
invitee_id, [Membership.LEAVE]
invitee_id, (Membership.LEAVE,)
)
)
self.assertEqual(len(memberships), 1, memberships)
Expand Down
2 changes: 1 addition & 1 deletion tests/storage/test_roommember.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def test_one_member(self) -> None:

rooms_for_user = self.get_success(
self.store.get_rooms_for_local_user_where_membership_is(
self.u_alice, [Membership.JOIN]
self.u_alice, (Membership.JOIN,)
)
)

Expand Down

0 comments on commit 7ef8f88

Please sign in to comment.