Skip to content

Commit

Permalink
Fix joining remote rooms when a on_new_event callback is registered
Browse files Browse the repository at this point in the history
Since Synapse 1.76.0, any module which registers a `on_new_event`
callback would brick the ability to join remote rooms. This is because
this callback tried to get the full state of the room, which would end
up in a deadlock.
  • Loading branch information
sandhose committed Mar 1, 2024
1 parent 2252bae commit 4f70dd8
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 16 deletions.
23 changes: 9 additions & 14 deletions synapse/module_api/callbacks/third_party_event_rules_callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ async def check_threepid_can_be_invited(
if len(self._check_threepid_can_be_invited_callbacks) == 0:
return True

state_events = await self._get_state_map_for_room(room_id)
state_events = await self._storage_controllers.state.get_current_state(room_id)

for callback in self._check_threepid_can_be_invited_callbacks:
try:
Expand Down Expand Up @@ -399,7 +399,7 @@ async def check_visibility_can_be_modified(
if len(self._check_visibility_can_be_modified_callbacks) == 0:
return True

state_events = await self._get_state_map_for_room(room_id)
state_events = await self._storage_controllers.state.get_current_state(room_id)

for callback in self._check_visibility_can_be_modified_callbacks:
try:
Expand Down Expand Up @@ -427,7 +427,13 @@ async def on_new_event(self, event_id: str) -> None:
return

event = await self.store.get_event(event_id)
state_events = await self._get_state_map_for_room(event.room_id)

# We *don't* want to wait for the full state here, because waiting for full
# state will persist event, which in turn will call this method.
# This would end up in a deadlock.
state_events = await self._storage_controllers.state.get_current_state(
event.room_id, await_full_state=False
)

for callback in self._on_new_event_callbacks:
try:
Expand Down Expand Up @@ -490,17 +496,6 @@ async def check_can_deactivate_user(
)
return True

async def _get_state_map_for_room(self, room_id: str) -> StateMap[EventBase]:
"""Given a room ID, return the state events of that room.
Args:
room_id: The ID of the room.
Returns:
A dict mapping (event type, state key) to state event.
"""
return await self._storage_controllers.state.get_current_state(room_id)

async def on_profile_update(
self, user_id: str, new_profile: ProfileInfo, by_admin: bool, deactivation: bool
) -> None:
Expand Down
9 changes: 7 additions & 2 deletions synapse/storage/controllers/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,10 +562,15 @@ async def get_current_state_deltas(
@trace
@tag_args
async def get_current_state(
self, room_id: str, state_filter: Optional[StateFilter] = None
self,
room_id: str,
state_filter: Optional[StateFilter] = None,
await_full_state: bool = True,
) -> StateMap[EventBase]:
"""Same as `get_current_state_ids` but also fetches the events"""
state_map_ids = await self.get_current_state_ids(room_id, state_filter)
state_map_ids = await self.get_current_state_ids(
room_id, state_filter, await_full_state
)

event_map = await self.stores.main.get_events(list(state_map_ids.values()))

Expand Down

0 comments on commit 4f70dd8

Please sign in to comment.