Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Faster joins: don't stall when a user joins during a fast join #14606

Merged
merged 23 commits into from
Feb 10, 2023
Merged
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
384ccf2
Faster joins: don't stale when an user joins during a fast join
Dec 2, 2022
615d303
Merge branch 'develop' into mv/join-during-fast-join
Dec 29, 2022
7c1e8cf
Only delete fw extrems on join if room state is not partial
MatMaul Dec 29, 2022
0c3bc68
Only call _clean_room_for_join if send_join was successful
MatMaul Dec 29, 2022
4f6c342
move already_partially_joined closer to its use to avoid races
MatMaul Dec 29, 2022
6aa72e1
Fallback to local join if a room is unpartial stated during remote join
Jan 2, 2023
d98994c
Move PartialStateConflictError to api.errors because of circular dep
Jan 2, 2023
02d285e
Merge branch 'develop' into mv/join-during-fast-join
Jan 2, 2023
9919405
Merge branch 'develop' into mv/join-during-fast-join
Jan 9, 2023
a24d07a
Small mistake
Jan 9, 2023
20d5d34
Merge branch 'develop' into mv/join-during-fast-join
Jan 27, 2023
9a934c1
fix up for #14882
Jan 27, 2023
5826574
fixup imports
Jan 27, 2023
1df7060
fixup exception docstring
Jan 27, 2023
bfba7bb
fixup: remove more defunct PartialStateConflictError handling
Jan 27, 2023
0ecd9ba
Avoid clobbering existing local memberships on a second partial join
Jan 31, 2023
a23a64f
fix trial tests
Jan 31, 2023
95a529c
fix typo in changelog
Feb 3, 2023
438d592
fixup docstring to explain what a None prev_membership means
Feb 4, 2023
cfb71f0
fixup: is_host_in_room was already accurate given partial state
Feb 4, 2023
4fcf84e
make partial statedness of state maps explicit
Feb 4, 2023
4da4eda
fix typos and line wrapping
Feb 4, 2023
e97b44d
fixup: comment wording
Feb 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merge branch 'develop' into mv/join-during-fast-join
  • Loading branch information
Sean Quah committed Jan 27, 2023
commit 20d5d3448e120141b01dda69a765e946818e8562
105 changes: 39 additions & 66 deletions synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,24 @@ async def do_invite_join(

self._federation_event_handler.room_queues[room_id] = []

is_host_joined = await self.store.is_host_joined(room_id, self.server_name)

if not is_host_joined:
# We may have old forward extremities lying around if the homeserver left
# the room completely in the past. Clear them out.
#
# Note that this check-then-clear is subject to races where
# * the homeserver is in the room and stops being in the room just after
# the check. We won't reset the forward extremities, but that's okay,
# since they will be almost up to date.
# * the homeserver is not in the room and starts being in the room just
# after the check. This can't happen, since `RoomMemberHandler` has a
# linearizer lock which prevents concurrent remote joins into the same
# room.
# In short, the races either have an acceptable outcome or should be
# impossible.
await self._clean_room_for_join(room_id)

try:
# Try the host we successfully got a response to /make_join/
# request first.
Expand Down Expand Up @@ -639,77 +657,32 @@ async def do_invite_join(
logger.debug("do_invite_join auth_chain: %s", auth_chain)
logger.debug("do_invite_join state: %s", state)

await self._clean_room_for_join(room_id)

# if this is the first time we've joined this room, it's time to add
# a row to `rooms` with the correct room version. If there's already a
# row there, we should override it, since it may have been populated
# based on an invite request which lied about the room version.
#
# federation_client.send_join has already checked that the room
# version in the received create event is the same as room_version_obj,
# so we can rely on it now.
#
await self.store.upsert_room_on_join(
room_id=room_id,
room_version=room_version_obj,
state_events=state,
)

already_partially_joined = await self.store.is_partial_state_room(room_id)
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.
await self.store.store_partial_state_room(
logger.debug("do_invite_join event: %s", event)

# if this is the first time we've joined this room, it's time to add
# a row to `rooms` with the correct room version. If there's already a
# row there, we should override it, since it may have been populated
# based on an invite request which lied about the room version.
#
# federation_client.send_join has already checked that the room
# version in the received create event is the same as room_version_obj,
# so we can rely on it now.
#
await self.store.upsert_room_on_join(
room_id=room_id,
room_version=room_version_obj,
state_events=state,
)

try:
max_stream_id = (
await self._federation_event_handler.process_remote_join(
origin,
room_id,
auth_chain,
state,
event,
room_version_obj,
partial_state=ret.partial_state,
)
)
except PartialStateConflictError as e:
# The homeserver was already in the room and it is no longer partial
# stated. We ought to be doing a local join instead.
# TODO(faster_joins): `_should_perform_remote_join` suggests that we may
# do a remote join for restricted rooms even if we have full state.
logger.error(
"Room %s was un-partial stated while processing remote join.",
room_id,
)
raise e
else:
# Record the join event id for future use (when we finish the full
# join). We have to do this after persisting the event to keep foreign
# key constraints intact.
if ret.partial_state:
await self.store.write_partial_state_rooms_join_event_id(
room_id, event.event_id
)
finally:
# Always kick off the background process that asynchronously fetches
# 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 and not already_partially_joined:
# Kick off the process of asynchronously fetching the state for this
# room.
run_as_background_process(
desc="sync_partial_state_room",
func=self._sync_partial_state_room,
initial_destination=origin,
other_destinations=ret.servers_in_room,
if ret.partial_state and not already_partial_state_room:
# Mark the room as having partial state.
# The background process is responsible for unmarking this flag,
# even if the join fails.
# TODO(faster_joins):
# We may want to reset the partial state info if it's from an
# old, failed partial state join.
# https://github.com/matrix-org/synapse/issues/13000
await self.store.store_partial_state_room(
room_id=room_id,
servers=ret.servers_in_room,
device_lists_stream_id=self.store.get_device_stream_token(),
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.