Repository: matrix-org/synapse

Issue:
Faster joins: room alias server list may be incomplete
If a room alias is added on a server that is doing a faster join, the list of servers associated with the alias may be incomplete until the faster join completes.


Discussion:
Currently we probably return just ourselves, which is useless. We should probably return the list of servers we got from the `/send_join`, which will be good enough.
(This is a bit of an edge-case as it's unlikely someone will add an alias (and then someone else will join through it) during a faster join)
The current situation is that we block waiting for full state:

```
  synapse_main |   File "/usr/local/lib/python3.9/site-packages/synapse/rest/client/directory.py", line 91, in on_PUT
  synapse_main |     await self.directory_handler.create_association(
  synapse_main |   File "/usr/local/lib/python3.9/site-packages/synapse/handlers/directory.py", line 175, in create_association
  synapse_main |     await self._create_association(room_alias, room_id, servers, creator=user_id)
  synapse_main |   File "/usr/local/lib/python3.9/site-packages/synapse/handlers/directory.py", line 88, in _create_association
  synapse_main |     servers = await self._storage_controllers.state.get_current_hosts_in_room(
  synapse_main |   File "/usr/local/lib/python3.9/site-packages/synapse/storage/controllers/state.py", line 539, in get_current_hosts_in_room
  synapse_main |     await self._partial_state_room_tracker.await_full_state(room_id)
  synapse_main |   File "/usr/local/lib/python3.9/site-packages/synapse/logging/opentracing.py", line 889, in _wrapper
  synapse_main |     return await func(*args, **kwargs)  # type: ignore[misc]
  synapse_main |   File "/usr/local/lib/python3.9/site-packages/synapse/storage/util/partial_state_events_tracker.py", line 172, in await_full_state
  synapse_main |     logger.info(
```

So we need to change that behaviour.

Also: do we persist the list of servers we get from a `send_join` response? Presumably this is what `partial_state_rooms_servers` is for?

Edit: ahh yes, get_partial_state_servers_at_join:

https://github.com/matrix-org/synapse/blob/c3a4780080a5bcb04132283c0f32f7452655792a/synapse/storage/databases/main/room.py#L1152-L1167

Resolving patch:
diff --git a/synapse/handlers/directory.py b/synapse/handlers/directory.py
--- a/synapse/handlers/directory.py
+++ b/synapse/handlers/directory.py
@@ -85,7 +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(
+            servers = await self._storage_controllers.state.get_current_hosts_in_room_or_partial_state_approximation(
                 room_id
             )
 
@@ -290,7 +290,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(
+        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)


Test patch: