Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 6258730

Browse files
authored
Consider the origin_server_ts of the m.space.child event when ordering rooms. (#10730)
This updates the ordering of the returned events from the spaces summary API to that defined in MSC2946 (which updates MSC1772). Previously a step was skipped causing ordering to be inconsistent with clients.
1 parent d1f1b46 commit 6258730

File tree

3 files changed

+22
-12
lines changed

3 files changed

+22
-12
lines changed

changelog.d/10730.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a bug where the ordering algorithm was skipping the `origin_server_ts` step in the spaces summary resulting in unstable room orderings.

synapse/handlers/room_summary.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,25 +1139,26 @@ def _is_suggested_child_event(edge_event: EventBase) -> bool:
11391139
_INVALID_ORDER_CHARS_RE = re.compile(r"[^\x20-\x7E]")
11401140

11411141

1142-
def _child_events_comparison_key(child: EventBase) -> Tuple[bool, Optional[str], str]:
1142+
def _child_events_comparison_key(
1143+
child: EventBase,
1144+
) -> Tuple[bool, Optional[str], int, str]:
11431145
"""
11441146
Generate a value for comparing two child events for ordering.
11451147
1146-
The rules for ordering are supposed to be:
1148+
The rules for ordering are:
11471149
11481150
1. The 'order' key, if it is valid.
1149-
2. The 'origin_server_ts' of the 'm.room.create' event.
1151+
2. The 'origin_server_ts' of the 'm.space.child' event.
11501152
3. The 'room_id'.
11511153
1152-
But we skip step 2 since we may not have any state from the room.
1153-
11541154
Args:
11551155
child: The event for generating a comparison key.
11561156
11571157
Returns:
11581158
The comparison key as a tuple of:
11591159
False if the ordering is valid.
1160-
The ordering field.
1160+
The 'order' field or None if it is not given or invalid.
1161+
The 'origin_server_ts' field.
11611162
The room ID.
11621163
"""
11631164
order = child.content.get("order")
@@ -1168,4 +1169,4 @@ def _child_events_comparison_key(child: EventBase) -> Tuple[bool, Optional[str],
11681169
order = None
11691170

11701171
# Items without an order come last.
1171-
return (order is None, order, child.room_id)
1172+
return (order is None, order, child.origin_server_ts, child.room_id)

tests/handlers/test_room_summary.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@
3535
from tests import unittest
3636

3737

38-
def _create_event(room_id: str, order: Optional[Any] = None):
39-
result = mock.Mock()
38+
def _create_event(room_id: str, order: Optional[Any] = None, origin_server_ts: int = 0):
39+
result = mock.Mock(name=room_id)
4040
result.room_id = room_id
4141
result.content = {}
42+
result.origin_server_ts = origin_server_ts
4243
if order is not None:
4344
result.content["order"] = order
4445
return result
@@ -63,10 +64,17 @@ def test_order(self):
6364

6465
self.assertEqual([ev2, ev1], _order(ev1, ev2))
6566

67+
def test_order_origin_server_ts(self):
68+
"""Origin server is a tie-breaker for ordering."""
69+
ev1 = _create_event("!abc:test", origin_server_ts=10)
70+
ev2 = _create_event("!xyz:test", origin_server_ts=30)
71+
72+
self.assertEqual([ev1, ev2], _order(ev1, ev2))
73+
6674
def test_order_room_id(self):
67-
"""Room ID is a tie-breaker for ordering."""
68-
ev1 = _create_event("!abc:test", "abc")
69-
ev2 = _create_event("!xyz:test", "abc")
75+
"""Room ID is a final tie-breaker for ordering."""
76+
ev1 = _create_event("!abc:test")
77+
ev2 = _create_event("!xyz:test")
7078

7179
self.assertEqual([ev1, ev2], _order(ev1, ev2))
7280

0 commit comments

Comments
 (0)