From 1e928ab8f8292537c6c4f16b883d0b18925eb682 Mon Sep 17 00:00:00 2001 From: Mathieu Velten Date: Fri, 2 Dec 2022 18:00:01 +0100 Subject: [PATCH] WIP Join during fast join Signed-off-by: Mathieu Velten --- changelog.d/14606.misc | 1 + synapse/handlers/federation.py | 6 ++++-- synapse/handlers/room_member.py | 17 ++++++++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 changelog.d/14606.misc diff --git a/changelog.d/14606.misc b/changelog.d/14606.misc new file mode 100644 index 000000000000..c6930c5721d4 --- /dev/null +++ b/changelog.d/14606.misc @@ -0,0 +1 @@ +Faster joins: handle join during fast join. diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py index eca75f1108d1..0d2e1700b949 100644 --- a/synapse/handlers/federation.py +++ b/synapse/handlers/federation.py @@ -599,6 +599,8 @@ async def do_invite_join( except ValueError: pass + already_partially_joined = await self.store.is_partial_state_room(room_id) + ret = await self.federation_client.send_join( host_list, event, room_version_obj ) @@ -629,7 +631,7 @@ async def do_invite_join( state_events=state, ) - if ret.partial_state: + if ret.partial_state and not already_partially_joined: # Mark the room as having partial state. # The background process is responsible for unmarking this flag, # even if the join fails. @@ -676,7 +678,7 @@ async def do_invite_join( # state for the room. # If the join failed, the background process is responsible for # cleaning up — including unmarking the room as a partial state room. - if ret.partial_state: + if ret.partial_state and not already_partially_joined: # Kick off the process of asynchronously fetching the state for this # room. run_as_background_process( diff --git a/synapse/handlers/room_member.py b/synapse/handlers/room_member.py index d236cc09b526..6978e49a1023 100644 --- a/synapse/handlers/room_member.py +++ b/synapse/handlers/room_member.py @@ -821,10 +821,25 @@ async def update_membership_locked( origin_server_ts=origin_server_ts, ) + is_partial_state_room = await self.store.is_partial_state_room(room_id) + + await_full_state = True + # Join is ok because instead of relying on the events to validate it if the + # server is already partially joined, we will do make_join-send_join + # + # Leave doesn't really need validation: if the target has been banned in the + # meantime, we should have received the event and if not, state res at fed + # level will take care of solving the discrepancy. + if is_partial_state_room: + if get_domain_from_id( + target.to_string() + ) == self._server_name and action in [Membership.JOIN, Membership.LEAVE]: + await_full_state = False + latest_event_ids = await self.store.get_prev_events_for_room(room_id) state_before_join = await self.state_handler.compute_state_after_events( - room_id, latest_event_ids + room_id, latest_event_ids, await_full_state=await_full_state ) # TODO: Refactor into dictionary of explicitly allowed transitions