From 3d151cf6897933f6ed876e367a8e1123d44aa477 Mon Sep 17 00:00:00 2001 From: David Robertson Date: Tue, 25 Oct 2022 17:03:50 +0100 Subject: [PATCH 1/4] Allow PUT/GET of aliases during faster join Rather than block waiting for full state to list all servers int he room, we use the servers we got in the /send_join response as an appxoimation. --- synapse/handlers/directory.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/synapse/handlers/directory.py b/synapse/handlers/directory.py index d52ebada6b70..1072e23d8a46 100644 --- a/synapse/handlers/directory.py +++ b/synapse/handlers/directory.py @@ -14,7 +14,7 @@ import logging import string -from typing import TYPE_CHECKING, Iterable, List, Optional +from typing import TYPE_CHECKING, Iterable, List, Optional, Set from typing_extensions import Literal @@ -85,9 +85,7 @@ async def _create_association( # TODO(erikj): Add transactions. # TODO(erikj): Check if there is a current association. if not servers: - servers = await self._storage_controllers.state.get_current_hosts_in_room( - room_id - ) + servers = await self._get_servers_known_to_be_in_room(room_id) if not servers: raise SynapseError(400, "Failed to get server list") @@ -96,6 +94,21 @@ async def _create_association( room_alias, room_id, servers, creator=creator ) + async def _get_servers_known_to_be_in_room(self, room_id: str) -> Set[str]: + if await self.store.is_partial_state_room(room_id): + # We don't have the full list of hosts in the room yet, but we do have + # some of them from the `/send_join` response. Use those to best-effort + # approximate the full list of servers in the room. + servers = set(await self.store.get_partial_state_servers_at_join(room_id)) + + # We are also in the room. + servers.add(self.server_name) + else: + servers = await self._storage_controllers.state.get_current_hosts_in_room( + room_id + ) + return servers + async def create_association( self, requester: Requester, @@ -290,9 +303,7 @@ async def get_association(self, room_alias: RoomAlias) -> JsonDict: Codes.NOT_FOUND, ) - extra_servers = await self._storage_controllers.state.get_current_hosts_in_room( - room_id - ) + extra_servers = await self._get_servers_known_to_be_in_room(room_id) servers_set = set(extra_servers) | set(servers) # If this server is in the list of servers, return it first. From e4f8582856e4b526e1b1878acf99cf7c86fa23f0 Mon Sep 17 00:00:00 2001 From: David Robertson Date: Tue, 25 Oct 2022 17:09:32 +0100 Subject: [PATCH 2/4] Changelog --- changelog.d/14292.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/14292.bugfix diff --git a/changelog.d/14292.bugfix b/changelog.d/14292.bugfix new file mode 100644 index 000000000000..4ed92f5cf250 --- /dev/null +++ b/changelog.d/14292.bugfix @@ -0,0 +1 @@ +Faster joins: do not block creation of or queries for room aliases during the resync. From 419e6c5b8633749c3bf700bd017017e21c6d7ea2 Mon Sep 17 00:00:00 2001 From: David Robertson Date: Tue, 1 Nov 2022 13:38:04 +0000 Subject: [PATCH 3/4] Use existing similar helper function instead --- synapse/handlers/directory.py | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/synapse/handlers/directory.py b/synapse/handlers/directory.py index 1072e23d8a46..d61ff05d1a2a 100644 --- a/synapse/handlers/directory.py +++ b/synapse/handlers/directory.py @@ -85,7 +85,9 @@ async def _create_association( # TODO(erikj): Add transactions. # TODO(erikj): Check if there is a current association. if not servers: - servers = await self._get_servers_known_to_be_in_room(room_id) + servers = await self._storage_controllers.state.get_current_hosts_in_room_or_partial_state_approximation( + room_id + ) if not servers: raise SynapseError(400, "Failed to get server list") @@ -94,21 +96,6 @@ async def _create_association( room_alias, room_id, servers, creator=creator ) - async def _get_servers_known_to_be_in_room(self, room_id: str) -> Set[str]: - if await self.store.is_partial_state_room(room_id): - # We don't have the full list of hosts in the room yet, but we do have - # some of them from the `/send_join` response. Use those to best-effort - # approximate the full list of servers in the room. - servers = set(await self.store.get_partial_state_servers_at_join(room_id)) - - # We are also in the room. - servers.add(self.server_name) - else: - servers = await self._storage_controllers.state.get_current_hosts_in_room( - room_id - ) - return servers - async def create_association( self, requester: Requester, @@ -303,7 +290,9 @@ async def get_association(self, room_alias: RoomAlias) -> JsonDict: Codes.NOT_FOUND, ) - extra_servers = await self._get_servers_known_to_be_in_room(room_id) + extra_servers = await self._storage_controllers.state.get_current_hosts_in_room_or_partial_state_approximation( + room_id + ) servers_set = set(extra_servers) | set(servers) # If this server is in the list of servers, return it first. From 11dc46f367e5e7594a425c08b21e89dd7597aace Mon Sep 17 00:00:00 2001 From: David Robertson Date: Tue, 1 Nov 2022 13:45:18 +0000 Subject: [PATCH 4/4] Fixup import list --- synapse/handlers/directory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapse/handlers/directory.py b/synapse/handlers/directory.py index d61ff05d1a2a..2ea52257cb9e 100644 --- a/synapse/handlers/directory.py +++ b/synapse/handlers/directory.py @@ -14,7 +14,7 @@ import logging import string -from typing import TYPE_CHECKING, Iterable, List, Optional, Set +from typing import TYPE_CHECKING, Iterable, List, Optional from typing_extensions import Literal