-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Faster joins: Refactor handling of servers in room #14954
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Faster room joins: Refactor internal handling of servers in room to never store an empty list. | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ | |
import logging | ||
from typing import ( | ||
TYPE_CHECKING, | ||
AbstractSet, | ||
Awaitable, | ||
Callable, | ||
Collection, | ||
|
@@ -110,8 +111,9 @@ class SendJoinResult: | |
# True if 'state' elides non-critical membership events | ||
partial_state: bool | ||
|
||
# if 'partial_state' is set, a list of the servers in the room (otherwise empty) | ||
servers_in_room: List[str] | ||
# If 'partial_state' is set, a set of the servers in the room (otherwise empty). | ||
# Always contains the server we joined off. | ||
servers_in_room: AbstractSet[str] | ||
|
||
|
||
class FederationClient(FederationBase): | ||
|
@@ -1152,23 +1154,32 @@ async def _execute(pdu: EventBase) -> None: | |
% (auth_chain_create_events,) | ||
) | ||
|
||
if response.members_omitted and not response.servers_in_room: | ||
raise InvalidResponseError( | ||
"members_omitted was set, but no servers were listed in the room" | ||
) | ||
servers_in_room = None | ||
if response.servers_in_room is not None: | ||
servers_in_room = set(response.servers_in_room) | ||
|
||
if response.members_omitted and not partial_state: | ||
raise InvalidResponseError( | ||
"members_omitted was set, but we asked for full state" | ||
) | ||
if response.members_omitted: | ||
if not servers_in_room: | ||
raise InvalidResponseError( | ||
"members_omitted was set, but no servers were listed in the room" | ||
) | ||
|
||
if not partial_state: | ||
raise InvalidResponseError( | ||
"members_omitted was set, but we asked for full state" | ||
) | ||
Comment on lines
+1167
to
+1170
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd recommend moving this above the destination check to have all the error checking up-front. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 163c68c. |
||
|
||
# `servers_in_room` is supposed to be a complete list. | ||
# Fix things up in case the remote homeserver is badly behaved. | ||
servers_in_room.add(destination) | ||
|
||
return SendJoinResult( | ||
event=event, | ||
state=signed_state, | ||
auth_chain=signed_auth, | ||
origin=destination, | ||
partial_state=response.members_omitted, | ||
servers_in_room=response.servers_in_room or [], | ||
servers_in_room=servers_in_room or frozenset(), | ||
) | ||
|
||
# MSC3083 defines additional error codes for room joins. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -447,7 +447,7 @@ async def handle_event(event: EventBase) -> None: | |
) | ||
) | ||
|
||
if len(partial_state_destinations) > 0: | ||
if partial_state_destinations is not None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I initially thought there was a bug here, where we would block on the full state of the room (below) when the server we joined off returned an empty list of servers in the room. But while writing this PR to fix the bug, I discovered that we validate that the list is truthy and so the bug can't happen. |
||
destinations = partial_state_destinations | ||
|
||
if destinations is None: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -859,6 +859,7 @@ async def handle_room_un_partial_stated(self, room_id: str) -> None: | |
known_hosts_at_join = await self.store.get_partial_state_servers_at_join( | ||
room_id | ||
) | ||
assert known_hosts_at_join is not None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be an error? Usually assertions are used for programming errors, but this seem to be input validation? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The assert can't (shouldn't?) ever be hit unless we've introduced a bug. This method is only run when we're about to finish syncing state. At that point the room is still partial stated, which implies we have a list of servers in it. |
||
potentially_changed_hosts.difference_update(known_hosts_at_join) | ||
|
||
potentially_changed_hosts.discard(self.server_name) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this fixing a bug? A potential bug? Or just clean-up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's somewhere in between fixing a potential bug and a clean up. Probably closer to a clean up.