Skip to content

Commit f1bd70e

Browse files
fix: provide remote servers a way to find out about an event created during the remote join handshake
1 parent d9feade commit f1bd70e

File tree

2 files changed

+56
-3
lines changed

2 files changed

+56
-3
lines changed

synapse/federation/federation_server.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,10 @@ async def on_send_join_request(
766766
event, context = await self._on_send_membership_event(
767767
origin, content, Membership.JOIN, room_id
768768
)
769+
# Collect this now, the internal metadata of event(which should have it) doesn't
770+
stream_ordering_of_join = (
771+
await self.store.get_current_room_stream_token_for_room_id(room_id)
772+
)
769773

770774
prev_state_ids = await context.get_prev_state_ids()
771775

@@ -806,6 +810,27 @@ async def on_send_join_request(
806810
"members_omitted": send_partial_state_response,
807811
}
808812

813+
# Check the forward extremities for the room here. If there is more than one, it
814+
# is likely that another event was created in the room during the
815+
# make_join/send_join handshake. Without being able to determine how long until
816+
# the next event will be created that references this 'missing event',
817+
# proactively send a dummy extensible event that ties these forward extremities
818+
# together. The remote server should search out this missing event on its own.
819+
#
820+
# By not sending the 'missing event' directly, the stream ordering for it will
821+
# be consistent between servers(in that it technically was created before the
822+
# join itself).
823+
824+
forward_extremities = await self.store._get_forward_extremeties_for_room(
825+
room_id, stream_ordering_of_join.get_max_stream_pos()
826+
)
827+
828+
if len(forward_extremities) > 1:
829+
# I do not feel it is necessary to set this onto the FederationServer class
830+
# itself. Its likelihood of being used is extremely low. Make it on-demand
831+
_creation_handler = self.hs.get_event_creation_handler()
832+
await _creation_handler._send_dummy_events_to_patch_room(room_id)
833+
809834
if servers_in_room is not None:
810835
resp["servers_in_room"] = list(servers_in_room)
811836

synapse/handlers/message.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2210,7 +2210,36 @@ async def _send_dummy_events_to_fill_extremities(self) -> None:
22102210
now = self.clock.time_msec()
22112211
self._rooms_to_exclude_from_dummy_event_insertion[room_id] = now
22122212

2213-
async def _send_dummy_event_for_room(self, room_id: str) -> bool:
2213+
async def _send_dummy_events_to_patch_room(self, room_id: str) -> None:
2214+
"""
2215+
Send a dummy event into this room to patch in a missed forward extremity.
2216+
This should only be triggered during a remote join if there was a forward
2217+
extremity that occurred during the make_join/send_join handshake.
2218+
"""
2219+
async with self._worker_lock_handler.acquire_read_write_lock(
2220+
NEW_EVENT_DURING_PURGE_LOCK_NAME, room_id, write=False
2221+
):
2222+
dummy_event_sent = await self._send_dummy_event_for_room(
2223+
room_id, proactively_send=True
2224+
)
2225+
2226+
if not dummy_event_sent:
2227+
# Did not find a valid user in the room, so remove from future attempts
2228+
# Exclusion is time limited, so the room will be rechecked in the future
2229+
# dependent on _DUMMY_EVENT_ROOM_EXCLUSION_EXPIRY
2230+
logger.info(
2231+
"Failed to send dummy event into room %s. Will exclude it from "
2232+
"future attempts until cache expires",
2233+
room_id,
2234+
)
2235+
# This mapping is room_id -> time of last attempt(in ms)
2236+
self._rooms_to_exclude_from_dummy_event_insertion[room_id] = (
2237+
self.clock.time_msec()
2238+
)
2239+
2240+
async def _send_dummy_event_for_room(
2241+
self, room_id: str, proactively_send: bool = False
2242+
) -> bool:
22142243
"""Attempt to send a dummy event for the given room.
22152244
22162245
Args:
@@ -2242,8 +2271,7 @@ async def _send_dummy_event_for_room(self, room_id: str) -> bool:
22422271
},
22432272
)
22442273
context = await unpersisted_context.persist(event)
2245-
2246-
event.internal_metadata.proactively_send = False
2274+
event.internal_metadata.proactively_send = proactively_send
22472275

22482276
# Since this is a dummy-event it is OK if it is sent by a
22492277
# shadow-banned user.

0 commit comments

Comments
 (0)