mirror of
https://mau.dev/maunium/synapse.git
synced 2024-10-01 01:36:05 -04:00
Speed up remote invite rejection database call (#8815)
This is another PR that grew out of #6739.
The existing code for checking whether a user is currently invited to a room when they want to leave the room looks like the following:
f737368a26/synapse/handlers/room_member.py (L518-L540)
It calls `get_invite_for_local_user_in_room`, which will actually query *all* rooms the user has been invited to, before iterating over them and matching via the room ID. It will then return a tuple of a lot of information which we pull the event ID out of.
I need to do a similar check for knocking, but this code wasn't very efficient. I then tried to write a different implementation using `StateHandler.get_current_state` but this actually didn't work as we haven't *joined* the room yet - we've only been invited to it. That means that only certain tables in Synapse have our desired `invite` membership state. One of those tables is `local_current_membership`.
So I wrote a store method that just queries that table instead
This commit is contained in:
parent
968939bdac
commit
d963c69ba5
1
changelog.d/8815.misc
Normal file
1
changelog.d/8815.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Optimise the lookup for an invite from another homeserver when trying to reject it.
|
@ -31,7 +31,6 @@ from synapse.api.errors import (
|
|||||||
from synapse.api.ratelimiting import Ratelimiter
|
from synapse.api.ratelimiting import Ratelimiter
|
||||||
from synapse.events import EventBase
|
from synapse.events import EventBase
|
||||||
from synapse.events.snapshot import EventContext
|
from synapse.events.snapshot import EventContext
|
||||||
from synapse.storage.roommember import RoomsForUser
|
|
||||||
from synapse.types import JsonDict, Requester, RoomAlias, RoomID, StateMap, UserID
|
from synapse.types import JsonDict, Requester, RoomAlias, RoomID, StateMap, UserID
|
||||||
from synapse.util.async_helpers import Linearizer
|
from synapse.util.async_helpers import Linearizer
|
||||||
from synapse.util.distributor import user_left_room
|
from synapse.util.distributor import user_left_room
|
||||||
@ -515,10 +514,16 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
|||||||
elif effective_membership_state == Membership.LEAVE:
|
elif effective_membership_state == Membership.LEAVE:
|
||||||
if not is_host_in_room:
|
if not is_host_in_room:
|
||||||
# perhaps we've been invited
|
# perhaps we've been invited
|
||||||
invite = await self.store.get_invite_for_local_user_in_room(
|
(
|
||||||
user_id=target.to_string(), room_id=room_id
|
current_membership_type,
|
||||||
) # type: Optional[RoomsForUser]
|
current_membership_event_id,
|
||||||
if not invite:
|
) = await self.store.get_local_current_membership_for_user_in_room(
|
||||||
|
target.to_string(), room_id
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
current_membership_type != Membership.INVITE
|
||||||
|
or not current_membership_event_id
|
||||||
|
):
|
||||||
logger.info(
|
logger.info(
|
||||||
"%s sent a leave request to %s, but that is not an active room "
|
"%s sent a leave request to %s, but that is not an active room "
|
||||||
"on this server, and there is no pending invite",
|
"on this server, and there is no pending invite",
|
||||||
@ -528,6 +533,7 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
|||||||
|
|
||||||
raise SynapseError(404, "Not a known room")
|
raise SynapseError(404, "Not a known room")
|
||||||
|
|
||||||
|
invite = await self.store.get_event(current_membership_event_id)
|
||||||
logger.info(
|
logger.info(
|
||||||
"%s rejects invite to %s from %s", target, room_id, invite.sender
|
"%s rejects invite to %s from %s", target, room_id, invite.sender
|
||||||
)
|
)
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING, Dict, FrozenSet, Iterable, List, Optional, Set
|
from typing import TYPE_CHECKING, Dict, FrozenSet, Iterable, List, Optional, Set, Tuple
|
||||||
|
|
||||||
from synapse.api.constants import EventTypes, Membership
|
from synapse.api.constants import EventTypes, Membership
|
||||||
from synapse.events import EventBase
|
from synapse.events import EventBase
|
||||||
@ -350,6 +350,38 @@ class RoomMemberWorkerStore(EventsWorkerStore):
|
|||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
async def get_local_current_membership_for_user_in_room(
|
||||||
|
self, user_id: str, room_id: str
|
||||||
|
) -> Tuple[Optional[str], Optional[str]]:
|
||||||
|
"""Retrieve the current local membership state and event ID for a user in a room.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user_id: The ID of the user.
|
||||||
|
room_id: The ID of the room.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A tuple of (membership_type, event_id). Both will be None if a
|
||||||
|
room_id/user_id pair is not found.
|
||||||
|
"""
|
||||||
|
# Paranoia check.
|
||||||
|
if not self.hs.is_mine_id(user_id):
|
||||||
|
raise Exception(
|
||||||
|
"Cannot call 'get_local_current_membership_for_user_in_room' on "
|
||||||
|
"non-local user %s" % (user_id,),
|
||||||
|
)
|
||||||
|
|
||||||
|
results_dict = await self.db_pool.simple_select_one(
|
||||||
|
"local_current_membership",
|
||||||
|
{"room_id": room_id, "user_id": user_id},
|
||||||
|
("membership", "event_id"),
|
||||||
|
allow_none=True,
|
||||||
|
desc="get_local_current_membership_for_user_in_room",
|
||||||
|
)
|
||||||
|
if not results_dict:
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
return results_dict.get("membership"), results_dict.get("event_id")
|
||||||
|
|
||||||
@cached(max_entries=500000, iterable=True)
|
@cached(max_entries=500000, iterable=True)
|
||||||
async def get_rooms_for_user_with_stream_ordering(
|
async def get_rooms_for_user_with_stream_ordering(
|
||||||
self, user_id: str
|
self, user_id: str
|
||||||
|
Loading…
Reference in New Issue
Block a user