Tie-break child ordering on the child room id

_child_events_comparison_key's final tie-break used the room the
m.space.child event lives in, which is the same for every child of a
space and so never broke a tie (leaving ties in arbitrary DB order). Use
the child room id (the event's state key), per the spec, matching the
cached path.
This commit is contained in:
Matthew Hodgson
2026-08-08 22:42:50 +03:00
parent 9ab988d6e1
commit 06e0494bca
2 changed files with 14 additions and 4 deletions
+7 -3
View File
@@ -1351,7 +1351,7 @@ def _child_events_comparison_key(
1. The 'order' key, if it is valid.
2. The 'origin_server_ts' of the 'm.space.child' event.
3. The 'room_id'.
3. The child room ID (the event's state key).
Args:
child: The event for generating a comparison key.
@@ -1361,7 +1361,7 @@ def _child_events_comparison_key(
False if the ordering is valid.
The 'order' field or None if it is not given or invalid.
The 'origin_server_ts' field.
The room ID.
The child room ID.
"""
order = child.content.get("order")
# If order is not a string or doesn't meet the requirements, ignore it.
@@ -1371,4 +1371,8 @@ def _child_events_comparison_key(
order = None
# Items without an order come last.
return order is None, order, child.origin_server_ts, child.room_id
#
# NB the final tie-break is the CHILD room id (the state key), not the room
# the event lives in — that is the same for every child of a space, so it
# never actually broke a tie.
return order is None, order, child.origin_server_ts, child.state_key
+7 -1
View File
@@ -51,8 +51,14 @@ from tests.unittest import override_config
def _create_event(
room_id: str, order: Any | None = None, origin_server_ts: int = 0
) -> mock.Mock:
"""Build a fake m.space.child event pointing at `room_id`.
The child room id is the event's state key (the event itself lives in the
parent space).
"""
result = mock.Mock(name=room_id)
result.room_id = room_id
result.state_key = room_id
result.room_id = "!parent:test"
result.content = {}
result.origin_server_ts = origin_server_ts
if order is not None: