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

Commit 494ebd7

Browse files
authored
Include bundled aggregations in /sync and related fixes (#11478)
Due to updates to MSC2675 this includes a few fixes: * Include bundled aggregations for /sync. * Do not include bundled aggregations for /initialSync and /events. * Do not bundle aggregations for state events. * Clarifies comments and variable names.
1 parent a77c369 commit 494ebd7

File tree

10 files changed

+169
-101
lines changed

10 files changed

+169
-101
lines changed

changelog.d/11478.bugfix

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Include bundled relation aggregations during a limited `/sync` request, per [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675).

synapse/events/utils.py

+35-23
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ def format_event_for_client_v2_without_room_id(d: JsonDict) -> JsonDict:
306306
def serialize_event(
307307
e: Union[JsonDict, EventBase],
308308
time_now_ms: int,
309+
*,
309310
as_client_event: bool = True,
310311
event_format: Callable[[JsonDict], JsonDict] = format_event_for_client_v1,
311312
token_id: Optional[str] = None,
@@ -393,16 +394,18 @@ async def serialize_event(
393394
self,
394395
event: Union[JsonDict, EventBase],
395396
time_now: int,
396-
bundle_relations: bool = True,
397+
*,
398+
bundle_aggregations: bool = True,
397399
**kwargs: Any,
398400
) -> JsonDict:
399401
"""Serializes a single event.
400402
401403
Args:
402404
event: The event being serialized.
403405
time_now: The current time in milliseconds
404-
bundle_relations: Whether to include the bundled relations for this
405-
event.
406+
bundle_aggregations: Whether to include the bundled aggregations for this
407+
event. Only applies to non-state events. (State events never include
408+
bundled aggregations.)
406409
**kwargs: Arguments to pass to `serialize_event`
407410
408411
Returns:
@@ -414,28 +417,35 @@ async def serialize_event(
414417

415418
serialized_event = serialize_event(event, time_now, **kwargs)
416419

417-
# If MSC1849 is enabled then we need to look if there are any relations
418-
# we need to bundle in with the event.
419-
# Do not bundle relations if the event has been redacted
420-
if not event.internal_metadata.is_redacted() and (
421-
self._msc1849_enabled and bundle_relations
420+
# Check if there are any bundled aggregations to include with the event.
421+
#
422+
# Do not bundle aggregations if any of the following at true:
423+
#
424+
# * Support is disabled via the configuration or the caller.
425+
# * The event is a state event.
426+
# * The event has been redacted.
427+
if (
428+
self._msc1849_enabled
429+
and bundle_aggregations
430+
and not event.is_state()
431+
and not event.internal_metadata.is_redacted()
422432
):
423-
await self._injected_bundled_relations(event, time_now, serialized_event)
433+
await self._injected_bundled_aggregations(event, time_now, serialized_event)
424434

425435
return serialized_event
426436

427-
async def _injected_bundled_relations(
437+
async def _injected_bundled_aggregations(
428438
self, event: EventBase, time_now: int, serialized_event: JsonDict
429439
) -> None:
430-
"""Potentially injects bundled relations into the unsigned portion of the serialized event.
440+
"""Potentially injects bundled aggregations into the unsigned portion of the serialized event.
431441
432442
Args:
433443
event: The event being serialized.
434444
time_now: The current time in milliseconds
435445
serialized_event: The serialized event which may be modified.
436446
437447
"""
438-
# Do not bundle relations for an event which represents an edit or an
448+
# Do not bundle aggregations for an event which represents an edit or an
439449
# annotation. It does not make sense for them to have related events.
440450
relates_to = event.content.get("m.relates_to")
441451
if isinstance(relates_to, (dict, frozendict)):
@@ -445,18 +455,18 @@ async def _injected_bundled_relations(
445455

446456
event_id = event.event_id
447457

448-
# The bundled relations to include.
449-
relations = {}
458+
# The bundled aggregations to include.
459+
aggregations = {}
450460

451461
annotations = await self.store.get_aggregation_groups_for_event(event_id)
452462
if annotations.chunk:
453-
relations[RelationTypes.ANNOTATION] = annotations.to_dict()
463+
aggregations[RelationTypes.ANNOTATION] = annotations.to_dict()
454464

455465
references = await self.store.get_relations_for_event(
456466
event_id, RelationTypes.REFERENCE, direction="f"
457467
)
458468
if references.chunk:
459-
relations[RelationTypes.REFERENCE] = references.to_dict()
469+
aggregations[RelationTypes.REFERENCE] = references.to_dict()
460470

461471
edit = None
462472
if event.type == EventTypes.Message:
@@ -482,7 +492,7 @@ async def _injected_bundled_relations(
482492
else:
483493
serialized_event["content"].pop("m.relates_to", None)
484494

485-
relations[RelationTypes.REPLACE] = {
495+
aggregations[RelationTypes.REPLACE] = {
486496
"event_id": edit.event_id,
487497
"origin_server_ts": edit.origin_server_ts,
488498
"sender": edit.sender,
@@ -495,17 +505,19 @@ async def _injected_bundled_relations(
495505
latest_thread_event,
496506
) = await self.store.get_thread_summary(event_id)
497507
if latest_thread_event:
498-
relations[RelationTypes.THREAD] = {
499-
# Don't bundle relations as this could recurse forever.
508+
aggregations[RelationTypes.THREAD] = {
509+
# Don't bundle aggregations as this could recurse forever.
500510
"latest_event": await self.serialize_event(
501-
latest_thread_event, time_now, bundle_relations=False
511+
latest_thread_event, time_now, bundle_aggregations=False
502512
),
503513
"count": thread_count,
504514
}
505515

506-
# If any bundled relations were found, include them.
507-
if relations:
508-
serialized_event["unsigned"].setdefault("m.relations", {}).update(relations)
516+
# If any bundled aggregations were found, include them.
517+
if aggregations:
518+
serialized_event["unsigned"].setdefault("m.relations", {}).update(
519+
aggregations
520+
)
509521

510522
async def serialize_events(
511523
self, events: Iterable[Union[JsonDict, EventBase]], time_now: int, **kwargs: Any

synapse/handlers/events.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,8 @@ async def get_stream(
122122
events,
123123
time_now,
124124
as_client_event=as_client_event,
125-
# We don't bundle "live" events, as otherwise clients
126-
# will end up double counting annotations.
127-
bundle_relations=False,
125+
# Don't bundle aggregations as this is a deprecated API.
126+
bundle_aggregations=False,
128127
)
129128

130129
chunk = {

synapse/handlers/initial_sync.py

+24-6
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,11 @@ async def handle_room(event: RoomsForUser) -> None:
165165

166166
invite_event = await self.store.get_event(event.event_id)
167167
d["invite"] = await self._event_serializer.serialize_event(
168-
invite_event, time_now, as_client_event
168+
invite_event,
169+
time_now,
170+
# Don't bundle aggregations as this is a deprecated API.
171+
bundle_aggregations=False,
172+
as_client_event=as_client_event,
169173
)
170174

171175
rooms_ret.append(d)
@@ -216,7 +220,11 @@ async def handle_room(event: RoomsForUser) -> None:
216220
d["messages"] = {
217221
"chunk": (
218222
await self._event_serializer.serialize_events(
219-
messages, time_now=time_now, as_client_event=as_client_event
223+
messages,
224+
time_now=time_now,
225+
# Don't bundle aggregations as this is a deprecated API.
226+
bundle_aggregations=False,
227+
as_client_event=as_client_event,
220228
)
221229
),
222230
"start": await start_token.to_string(self.store),
@@ -226,6 +234,8 @@ async def handle_room(event: RoomsForUser) -> None:
226234
d["state"] = await self._event_serializer.serialize_events(
227235
current_state.values(),
228236
time_now=time_now,
237+
# Don't bundle aggregations as this is a deprecated API.
238+
bundle_aggregations=False,
229239
as_client_event=as_client_event,
230240
)
231241

@@ -366,14 +376,18 @@ async def _room_initial_sync_parted(
366376
"room_id": room_id,
367377
"messages": {
368378
"chunk": (
369-
await self._event_serializer.serialize_events(messages, time_now)
379+
# Don't bundle aggregations as this is a deprecated API.
380+
await self._event_serializer.serialize_events(
381+
messages, time_now, bundle_aggregations=False
382+
)
370383
),
371384
"start": await start_token.to_string(self.store),
372385
"end": await end_token.to_string(self.store),
373386
},
374387
"state": (
388+
# Don't bundle aggregations as this is a deprecated API.
375389
await self._event_serializer.serialize_events(
376-
room_state.values(), time_now
390+
room_state.values(), time_now, bundle_aggregations=False
377391
)
378392
),
379393
"presence": [],
@@ -392,8 +406,9 @@ async def _room_initial_sync_joined(
392406

393407
# TODO: These concurrently
394408
time_now = self.clock.time_msec()
409+
# Don't bundle aggregations as this is a deprecated API.
395410
state = await self._event_serializer.serialize_events(
396-
current_state.values(), time_now
411+
current_state.values(), time_now, bundle_aggregations=False
397412
)
398413

399414
now_token = self.hs.get_event_sources().get_current_token()
@@ -467,7 +482,10 @@ async def get_receipts() -> List[JsonDict]:
467482
"room_id": room_id,
468483
"messages": {
469484
"chunk": (
470-
await self._event_serializer.serialize_events(messages, time_now)
485+
# Don't bundle aggregations as this is a deprecated API.
486+
await self._event_serializer.serialize_events(
487+
messages, time_now, bundle_aggregations=False
488+
)
471489
),
472490
"start": await start_token.to_string(self.store),
473491
"end": await end_token.to_string(self.store),

synapse/handlers/message.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -247,13 +247,7 @@ async def get_state_events(
247247
room_state = room_state_events[membership_event_id]
248248

249249
now = self.clock.time_msec()
250-
events = await self._event_serializer.serialize_events(
251-
room_state.values(),
252-
now,
253-
# We don't bother bundling aggregations in when asked for state
254-
# events, as clients won't use them.
255-
bundle_relations=False,
256-
)
250+
events = await self._event_serializer.serialize_events(room_state.values(), now)
257251
return events
258252

259253
async def get_joined_members(self, requester: Requester, room_id: str) -> dict:

synapse/rest/admin/rooms.py

+2-11
Original file line numberDiff line numberDiff line change
@@ -449,13 +449,7 @@ async def on_GET(
449449
event_ids = await self.store.get_current_state_ids(room_id)
450450
events = await self.store.get_events(event_ids.values())
451451
now = self.clock.time_msec()
452-
room_state = await self._event_serializer.serialize_events(
453-
events.values(),
454-
now,
455-
# We don't bother bundling aggregations in when asked for state
456-
# events, as clients won't use them.
457-
bundle_relations=False,
458-
)
452+
room_state = await self._event_serializer.serialize_events(events.values(), now)
459453
ret = {"state": room_state}
460454

461455
return HTTPStatus.OK, ret
@@ -789,10 +783,7 @@ async def on_GET(
789783
results["events_after"], time_now
790784
)
791785
results["state"] = await self._event_serializer.serialize_events(
792-
results["state"],
793-
time_now,
794-
# No need to bundle aggregations for state events
795-
bundle_relations=False,
786+
results["state"], time_now
796787
)
797788

798789
return HTTPStatus.OK, results

synapse/rest/client/relations.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,13 @@ async def on_GET(
224224
)
225225

226226
now = self.clock.time_msec()
227-
# We set bundle_relations to False when retrieving the original
228-
# event because we want the content before relations were applied to
229-
# it.
227+
# Do not bundle aggregations when retrieving the original event because
228+
# we want the content before relations are applied to it.
230229
original_event = await self._event_serializer.serialize_event(
231-
event, now, bundle_relations=False
230+
event, now, bundle_aggregations=False
232231
)
233232
# The relations returned for the requested event do include their
234-
# bundled relations.
233+
# bundled aggregations.
235234
serialized_events = await self._event_serializer.serialize_events(events, now)
236235

237236
return_value = pagination_chunk.to_dict()

synapse/rest/client/room.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -716,10 +716,7 @@ async def on_GET(
716716
results["events_after"], time_now
717717
)
718718
results["state"] = await self._event_serializer.serialize_events(
719-
results["state"],
720-
time_now,
721-
# No need to bundle aggregations for state events
722-
bundle_relations=False,
719+
results["state"], time_now
723720
)
724721

725722
return 200, results

synapse/rest/client/sync.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -520,9 +520,9 @@ def serialize(events: Iterable[EventBase]) -> Awaitable[List[JsonDict]]:
520520
return self._event_serializer.serialize_events(
521521
events,
522522
time_now=time_now,
523-
# We don't bundle "live" events, as otherwise clients
524-
# will end up double counting annotations.
525-
bundle_relations=False,
523+
# Don't bother to bundle aggregations if the timeline is unlimited,
524+
# as clients will have all the necessary information.
525+
bundle_aggregations=room.timeline.limited,
526526
token_id=token_id,
527527
event_format=event_formatter,
528528
only_event_fields=only_fields,

0 commit comments

Comments
 (0)