Skip to content

Commit 1702b7c

Browse files
committed
Order heroes by stream_ordering
Split off from #17419 (comment)
1 parent 606da39 commit 1702b7c

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

synapse/storage/databases/main/roommember.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,19 @@ def _get_users_in_room_with_profiles(
279279

280280
@cached(max_entries=100000) # type: ignore[synapse-@cached-mutable]
281281
async def get_room_summary(self, room_id: str) -> Mapping[str, MemberSummary]:
282-
"""Get the details of a room roughly suitable for use by the room
282+
"""
283+
Get the details of a room roughly suitable for use by the room
283284
summary extension to /sync. Useful when lazy loading room members.
285+
286+
Returns the total count of members in the room by membership type, and a
287+
truncated list of members (the heroes). This will be the first 6 members of the
288+
room:
289+
- We want 5 heroes plus 1, in case one of them is the
290+
calling user.
291+
- They are ordered by `stream_ordering`, which are joined or
292+
invited. When no joined or invited members are available, this also includes
293+
banned and left users.
294+
284295
Args:
285296
room_id: The room ID to query
286297
Returns:
@@ -308,23 +319,28 @@ def _get_room_summary_txn(
308319
for count, membership in txn:
309320
res.setdefault(membership, MemberSummary([], count))
310321

311-
# we order by membership and then fairly arbitrarily by event_id so
312-
# heroes are consistent
313-
# Note, rejected events will have a null membership field, so
314-
# we we manually filter them out.
322+
# Order by membership (joins -> invites -> leave (former insiders) -> everything else
323+
# including knocks since they are outsiders), then by `stream_ordering` so
324+
# the first members in the room show up first and to make the sort stable
325+
# (consistent heroes).
326+
#
327+
# Note: rejected events will have a null membership field, so we we manually
328+
# filter them out.
315329
sql = """
316330
SELECT state_key, membership, event_id
317331
FROM current_state_events
318332
WHERE type = 'm.room.member' AND room_id = ?
319333
AND membership IS NOT NULL
320334
ORDER BY
321-
CASE membership WHEN ? THEN 1 WHEN ? THEN 2 ELSE 3 END ASC,
322-
event_id ASC
335+
CASE membership WHEN ? THEN 1 WHEN ? THEN 2 WHEN ? THEN 3 ELSE 4 END ASC,
336+
event_stream_ordering ASC
323337
LIMIT ?
324338
"""
325339

326340
# 6 is 5 (number of heroes) plus 1, in case one of them is the calling user.
327-
txn.execute(sql, (room_id, Membership.JOIN, Membership.INVITE, 6))
341+
txn.execute(
342+
sql, (room_id, Membership.JOIN, Membership.INVITE, Membership.LEAVE, 6)
343+
)
328344
for user_id, membership, event_id in txn:
329345
summary = res[membership]
330346
# we will always have a summary for this membership type at this

0 commit comments

Comments
 (0)