Reduce event lookups during room creation by passing known event IDs (#13210)
Inspired by the room batch handler, this uses previous event inserts to pre-populate prev events during room creation, reducing the number of queries required to create a room. Signed off by Nick @ Beeper (@Fizzadar)pull/13257/head
parent
11f811470f
commit
92202ce867
|
@ -0,0 +1 @@
|
||||||
|
Reduce number of events queried during room creation. Contributed by Nick @ Beeper (@fizzadar).
|
|
@ -1019,6 +1019,8 @@ class RoomCreationHandler:
|
||||||
|
|
||||||
event_keys = {"room_id": room_id, "sender": creator_id, "state_key": ""}
|
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:
|
def create(etype: str, content: JsonDict, **kwargs: Any) -> JsonDict:
|
||||||
e = {"type": etype, "content": content}
|
e = {"type": etype, "content": content}
|
||||||
|
|
||||||
|
@ -1028,19 +1030,27 @@ class RoomCreationHandler:
|
||||||
return e
|
return e
|
||||||
|
|
||||||
async def send(etype: str, content: JsonDict, **kwargs: Any) -> int:
|
async def send(etype: str, content: JsonDict, **kwargs: Any) -> int:
|
||||||
|
nonlocal last_sent_event_id
|
||||||
|
|
||||||
event = create(etype, content, **kwargs)
|
event = create(etype, content, **kwargs)
|
||||||
logger.debug("Sending %s in new room", etype)
|
logger.debug("Sending %s in new room", etype)
|
||||||
# Allow these events to be sent even if the user is shadow-banned to
|
# Allow these events to be sent even if the user is shadow-banned to
|
||||||
# allow the room creation to complete.
|
# allow the room creation to complete.
|
||||||
(
|
(
|
||||||
_,
|
sent_event,
|
||||||
last_stream_id,
|
last_stream_id,
|
||||||
) = await self.event_creation_handler.create_and_send_nonmember_event(
|
) = await self.event_creation_handler.create_and_send_nonmember_event(
|
||||||
creator,
|
creator,
|
||||||
event,
|
event,
|
||||||
ratelimit=False,
|
ratelimit=False,
|
||||||
ignore_shadow_ban=True,
|
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
|
return last_stream_id
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -1054,7 +1064,9 @@ class RoomCreationHandler:
|
||||||
await send(etype=EventTypes.Create, content=creation_content)
|
await send(etype=EventTypes.Create, content=creation_content)
|
||||||
|
|
||||||
logger.debug("Sending %s in new room", EventTypes.Member)
|
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,
|
||||||
creator.user,
|
creator.user,
|
||||||
room_id,
|
room_id,
|
||||||
|
@ -1062,7 +1074,9 @@ class RoomCreationHandler:
|
||||||
ratelimit=ratelimit,
|
ratelimit=ratelimit,
|
||||||
content=creator_join_profile,
|
content=creator_join_profile,
|
||||||
new_room=True,
|
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
|
# We treat the power levels override specially as this needs to be one
|
||||||
# of the first events that get sent into a room.
|
# of the first events that get sent into a room.
|
||||||
|
|
|
@ -708,6 +708,21 @@ class RoomsCreateTestCase(RoomBase):
|
||||||
|
|
||||||
self.assertEqual(200, channel.code, channel.result)
|
self.assertEqual(200, channel.code, channel.result)
|
||||||
self.assertTrue("room_id" in channel.json_body)
|
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:
|
def test_post_room_visibility_key(self) -> None:
|
||||||
# POST with visibility config key, expect new room id
|
# POST with visibility config key, expect new room id
|
||||||
|
|
Loading…
Reference in New Issue