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

Reduce event lookups during room creation by passing known event IDs #13210

Merged
1 change: 1 addition & 0 deletions changelog.d/13210.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reduce number of events queried during room creation. Contributed by Nick @ Beeper (@fizzadar).
18 changes: 16 additions & 2 deletions synapse/handlers/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,8 @@ async def _send_events_for_new_room(

event_keys = {"room_id": room_id, "sender": creator_id, "state_key": ""}

last_sent_event_id: Optional[str] = None

def create(etype: str, content: JsonDict, **kwargs: Any) -> JsonDict:
e = {"type": etype, "content": content}

Expand All @@ -1020,19 +1022,27 @@ def create(etype: str, content: JsonDict, **kwargs: Any) -> JsonDict:
return e

async def send(etype: str, content: JsonDict, **kwargs: Any) -> int:
nonlocal last_sent_event_id

event = create(etype, content, **kwargs)
logger.debug("Sending %s in new room", etype)
# Allow these events to be sent even if the user is shadow-banned to
# allow the room creation to complete.
(
_,
sent_event,
last_stream_id,
) = await self.event_creation_handler.create_and_send_nonmember_event(
creator,
event,
ratelimit=False,
ignore_shadow_ban=True,
# Note: we don't pass state_event_ids here because this triggers
# an additional query per event to look them up from the events table.
prev_event_ids=[last_sent_event_id] if last_sent_event_id else [],
)

last_sent_event_id = sent_event.event_id

return last_stream_id

try:
Expand All @@ -1046,15 +1056,19 @@ async def send(etype: str, content: JsonDict, **kwargs: Any) -> int:
await send(etype=EventTypes.Create, content=creation_content)

logger.debug("Sending %s in new room", EventTypes.Member)
await self.room_member_handler.update_membership(
# Room create event must exist at this point
assert last_sent_event_id is not None
member_event_id, _ = await self.room_member_handler.update_membership(
creator,
creator.user,
room_id,
"join",
ratelimit=ratelimit,
content=creator_join_profile,
new_room=True,
prev_event_ids=[last_sent_event_id],
)
last_sent_event_id = member_event_id

# We treat the power levels override specially as this needs to be one
# of the first events that get sent into a room.
Expand Down
15 changes: 15 additions & 0 deletions tests/rest/client/test_rooms.py
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,21 @@ def test_post_room_no_keys(self) -> None:

self.assertEqual(200, channel.code, channel.result)
self.assertTrue("room_id" in channel.json_body)
assert channel.resource_usage is not None
self.assertEqual(33, channel.resource_usage.db_txn_count)

def test_post_room_initial_state(self) -> None:
# POST with initial_state config key, expect new room id
channel = self.make_request(
"POST",
"/createRoom",
b'{"initial_state":[{"type": "m.bridge", "content": {}}]}',
)

self.assertEqual(200, channel.code, channel.result)
self.assertTrue("room_id" in channel.json_body)
assert channel.resource_usage is not None
self.assertEqual(37, channel.resource_usage.db_txn_count)

def test_post_room_visibility_key(self) -> None:
# POST with visibility config key, expect new room id
Expand Down