-
Notifications
You must be signed in to change notification settings - Fork 422
MSC4171 Omit service members from room summary #17866
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 13 commits
ec91bea
027a86c
587b687
d9c52b2
656996a
21c4677
7e6ae4f
b13a032
b84e949
990e2ce
9567c14
0ab5dae
d5530ff
0a8d85b
1da2f61
5b8cbf4
e60d4cf
5a3cdf2
6c17ee1
7521b78
429381a
ee13e3f
2c181a7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Add support for filtering out "service members" from room summary responses, as described in MSC4171. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -306,7 +306,7 @@ async def get_room_summary(self, room_id: str) -> Mapping[str, MemberSummary]: | |
| """ | ||
|
|
||
| def _get_room_summary_txn( | ||
| txn: LoggingTransaction, | ||
| txn: LoggingTransaction, exclude_members: List[str] | ||
| ) -> Dict[str, MemberSummary]: | ||
| # first get counts. | ||
| # We do this all in one transaction to keep the cache small. | ||
|
|
@@ -318,6 +318,10 @@ def _get_room_summary_txn( | |
| for membership, count in counts.items(): | ||
| res.setdefault(membership, MemberSummary([], count)) | ||
|
|
||
| exclude_users_clause, args = make_in_list_sql_clause( | ||
| self.database_engine, "state_key", exclude_members, negative=True | ||
| ) | ||
|
Comment on lines
+324
to
+326
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should be careful about there being too many Alternatively, we could just fetch N extra members like we do in case one of them is the calling user and do the exclusion outside of the SQL. But we should probably have a limit on that as well. Perhaps something to clarify in the spec and then we can bail if the list is longer than the specc'ed max. Perhaps we just rely on max length of an event?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was going to rely on the max length of an event, which I think even if you had a long list of very short userIds would still only be up to about 9k or so (once you've included the usual event padding). I'm not quite sure on the performance cost here, but I'd assume that a 9k string list filter in postgres isn't terrible as it's not going to impact IO. Alternatively we could do as you say and set a sensible max number of users in the spec (say 100 or so). I'm generally a bit allergic to limitations in the spec, as someones probably going to come up with a use case of 101 members however it might be justified in the case of performance.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, and
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We tend to limit We should at-least add a comment here that we are assuming that there should be no more than 9.3k members to exclude based on the max length of an event (65535 bytes).
We could have a valid MXID check and add them to a Perhaps we should just have a practical limit to re-evaluate if someone hits it. Have a 1k check and set |
||
|
|
||
| # Order by membership (joins -> invites -> leave (former insiders) -> | ||
| # everything else (outsiders like bans/knocks), then by `stream_ordering` so | ||
| # the first members in the room show up first and to make the sort stable | ||
|
|
@@ -330,16 +334,18 @@ def _get_room_summary_txn( | |
| FROM current_state_events | ||
| WHERE type = 'm.room.member' AND room_id = ? | ||
| AND membership IS NOT NULL | ||
| AND %s | ||
| ORDER BY | ||
| CASE membership WHEN ? THEN 1 WHEN ? THEN 2 WHEN ? THEN 3 ELSE 4 END ASC, | ||
| event_stream_ordering ASC | ||
| LIMIT ? | ||
| """ | ||
| """ % (exclude_users_clause) | ||
|
||
|
|
||
| txn.execute( | ||
| sql, | ||
| ( | ||
| room_id, | ||
| *args, | ||
| # Sort order | ||
| Membership.JOIN, | ||
| Membership.INVITE, | ||
|
|
@@ -357,8 +363,31 @@ def _get_room_summary_txn( | |
|
|
||
| return res | ||
|
|
||
| functional_members_event_id = await self.db_pool.simple_select_one_onecol( | ||
| table="current_state_events", | ||
| keyvalues={ | ||
| "room_id": room_id, | ||
| "type": EventTypes.MSC4171FunctionalMembers, | ||
| "state_key": "", | ||
| }, | ||
| retcol="event_id", | ||
| allow_none=True, | ||
| ) | ||
|
|
||
| exclude_members = [] | ||
| if functional_members_event_id: | ||
| functional_members_event = await self.get_event(functional_members_event_id) | ||
| functional_members_data = functional_members_event.content.get( | ||
| "service_members" | ||
| ) | ||
| # ONLY use this value if this looks like a valid list of strings. Otherwise, ignore. | ||
| if isinstance(functional_members_data, list) and all( | ||
| isinstance(item, str) for item in functional_members_data | ||
| ): | ||
| exclude_members = functional_members_data | ||
|
||
|
|
||
| return await self.db_pool.runInteraction( | ||
| "get_room_summary", _get_room_summary_txn | ||
| "get_room_summary", _get_room_summary_txn, exclude_members | ||
| ) | ||
|
|
||
| @cached() | ||
|
|
@@ -1754,7 +1783,8 @@ def __init__( | |
|
|
||
|
|
||
| def extract_heroes_from_room_summary( | ||
| details: Mapping[str, MemberSummary], me: str | ||
| details: Mapping[str, MemberSummary], | ||
| me: str, | ||
| ) -> List[str]: | ||
| """Determine the users that represent a room, from the perspective of the `me` user. | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.