Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sliding Sync: bugfix: ensure we can sync with SSS even with missing rooms #17727

Merged
merged 3 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions changelog.d/17727.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug in SSS which could prevent /sync from working for certain user accounts.
6 changes: 5 additions & 1 deletion synapse/storage/databases/main/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -1469,6 +1469,10 @@ async def bulk_get_last_event_pos_in_room_before_stream_ordering(
recheck_rooms: Set[str] = set()
min_token = end_token.stream
for room_id, stream in uncapped_results.items():
if stream is None:
# Despite the function not directly setting None, the cache can!
# See: https://github.com/element-hq/synapse/issues/17726
continue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is continuing the right thing to do here?
Or should this fall into the else case below for further processing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm following the same semantics as if the room was not in uncapped_results at all, which seems to just ignore the room entirely.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that makes sense to me. (This is my first time reading through all this code & it seems to jump around / duplicate itself in places which was a little confusing)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The caller of this function seems to expect an entry for each room ID?

joined_room_positions = (
await self.store.bulk_get_last_event_pos_in_room_before_stream_ordering(
[
room_id
for room_id, room_for_user in sync_room_map.items()
if room_for_user.membership == Membership.JOIN
],
to_token.room_key,
)
)
last_activity_in_room_map.update(joined_room_positions)
return sorted(
sync_room_map.values(),
# Sort by the last activity (stream_ordering) in the room
key=lambda room_info: last_activity_in_room_map[room_info.room_id],
# We want descending order
reverse=True,
)

It looks to me that things have gotten a bit confused here around what to do if a bump stamp can't be found, as we are probably assuming we can always find a bump stamp?

I guess the right thing to do is actually handle missing bump stamps at the call site (on top of this change)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this was due to room with an unknown room version.

Have fixed and added regression test in #17733

if stream <= min_token:
results[room_id] = stream
else:
Expand All @@ -1495,7 +1499,7 @@ async def _get_max_event_pos(self, room_id: str) -> int:
@cachedList(cached_method_name="_get_max_event_pos", list_name="room_ids")
async def _bulk_get_max_event_pos(
self, room_ids: StrCollection
) -> Mapping[str, int]:
) -> Mapping[str, Optional[int]]:
"""Fetch the max position of a persisted event in the room."""

# We need to be careful not to return positions ahead of the current
Expand Down
Loading