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

Commit 3504edb

Browse files
update read_marker so receipts aren't sent to large rooms
1 parent c32b9ce commit 3504edb

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

synapse/handlers/account_data.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,12 @@ async def _notify_modules(
9999
logger.exception("Failed to run module callback %s: %s", callback, e)
100100

101101
async def add_account_data_to_room(
102-
self, user_id: str, room_id: str, account_data_type: str, content: JsonDict
102+
self,
103+
user_id: str,
104+
room_id: str,
105+
account_data_type: str,
106+
content: JsonDict,
107+
notify_ephemeral: bool = True,
103108
) -> int:
104109
"""Add some account_data to a room for a user.
105110
@@ -108,6 +113,7 @@ async def add_account_data_to_room(
108113
room_id: The room to add a tag for.
109114
account_data_type: The type of account_data to add.
110115
content: A json object to associate with the tag.
116+
notify_ephemeral: Should ephemeral events be notified.
111117
112118
Returns:
113119
The maximum stream ID.
@@ -116,6 +122,8 @@ async def add_account_data_to_room(
116122
max_stream_id = await self._store.add_account_data_to_room(
117123
user_id, room_id, account_data_type, content
118124
)
125+
if not notify_ephemeral:
126+
return max_stream_id
119127

120128
self._notifier.on_new_event(
121129
StreamKeyType.ACCOUNT_DATA, max_stream_id, users=[user_id]
@@ -125,12 +133,15 @@ async def add_account_data_to_room(
125133

126134
return max_stream_id
127135
else:
136+
# TODO: beeper - work out how to test this? is only one instance supported?
137+
# https://github.com/beeper/synapse/blob/14f26a62d45f7de100070f3ae54b311a69200022/synapse/config/workers.py#L60
128138
response = await self._add_room_data_client(
129139
instance_name=random.choice(self._account_data_writers),
130140
user_id=user_id,
131141
room_id=room_id,
132142
account_data_type=account_data_type,
133143
content=content,
144+
notify_ephemeral=notify_ephemeral
134145
)
135146
return response["max_stream_id"]
136147

synapse/handlers/read_marker.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import logging
1616
from typing import TYPE_CHECKING, Optional
1717

18+
from synapse.api.constants import RECEIPTS_MAX_ROOM_SIZE
1819
from synapse.types import JsonDict
1920
from synapse.util.async_helpers import Linearizer
2021

@@ -58,8 +59,11 @@ async def received_client_read_marker(
5859
event_id, existing_read_marker["event_id"]
5960
)
6061

62+
num_users = await self.store.get_number_joined_users_in_room(room_id)
63+
should_send_reciepts = num_users <= RECEIPTS_MAX_ROOM_SIZE
64+
6165
if should_update:
6266
content = {"event_id": event_id, **(extra_content or {})}
6367
await self.account_data_handler.add_account_data_to_room(
64-
user_id, room_id, "m.fully_read", content
68+
user_id, room_id, "m.fully_read", content, notify_ephemeral=should_send_reciepts
6569
)

tests/rest/client/test_sync.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,31 @@ def test_read_receipt_not_sent_to_large_rooms(self) -> None:
530530
# Test that we didn't get a read receipt.
531531
self.assertIsNone(self._get_read_receipt())
532532

533+
def test_read_marker_doesnt_send_receipt_to_large_rooms(self) -> None:
534+
# Beeper: we don't send read receipts on rooms with over 100 users
535+
# add another 100 users to the room
536+
for i in range(RECEIPTS_MAX_ROOM_SIZE):
537+
user = self.register_user(f"user_{i}", f"secure_password_{i}")
538+
tok = self.login(f"user_{i}", f"secure_password_{i}")
539+
self.helper.join(room=self.room_id, user=user, tok=tok)
540+
541+
for receipt_type in (ReceiptTypes.FULLY_READ, ReceiptTypes.READ_PRIVATE):
542+
res = self.helper.send(
543+
self.room_id, body="woah, this is a big room!", tok=self.tok
544+
)
545+
546+
# Send a read receipt
547+
channel = self.make_request(
548+
"POST",
549+
f"/rooms/{self.room_id}/read_markers",
550+
{receipt_type: res["event_id"]},
551+
access_token=self.tok2,
552+
)
553+
554+
self.assertEqual(channel.code, 200, channel.json_body)
555+
# Test that we didn't get a read receipt.
556+
self.assertIsNone(self._get_read_receipt())
557+
533558
def _get_read_receipt(self) -> Optional[JsonDict]:
534559
"""Syncs and returns the read receipt."""
535560

0 commit comments

Comments
 (0)