From e7ed8a23ce1e2e4c11484e1ffcda728730c56b22 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 14:42:00 -0600 Subject: [PATCH 01/18] Move lazy loading filter options to event filter The options also work on /messages --- .../definitions/room_event_filter.yaml | 25 ++++++++++++++++ .../definitions/sync_filter.yaml | 29 +------------------ 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index aa217d2b2f4..fd399913294 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -16,6 +16,31 @@ allOf: - type: object title: RoomEventFilter properties: + lazy_load_members: + type: boolean + description: |- + If ``true``, the only ``m.room.member`` events returned in + the ``state`` section of the ``/sync`` response are those + which are definitely necessary for a client to display + the ``sender`` of the timeline events in that response. + If ``false``, ``m.room.member`` events are not filtered. + By default, servers should suppress duplicate redundant + lazy-loaded ``m.room.member`` events from being sent to a given + client across multiple calls to ``/sync``, given that most clients + cache membership events (see ``include_redundant_members`` + to change this behaviour). + include_redundant_members: + type: boolean + description: |- + If ``true``, the ``state`` section of the ``/sync`` response will + always contain the ``m.room.member`` events required to display + the ``sender`` of the timeline events in that response, assuming + ``lazy_load_members`` is enabled. This means that redundant + duplicate member events may be returned across multiple calls to + ``/sync``. This is useful for naive clients who never track + membership data. If ``false``, duplicate ``m.room.member`` events + may be suppressed by the server across multiple calls to ``/sync``. + If ``lazy_load_members`` is ``false`` this field is ignored. not_rooms: description: A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the ``'rooms'`` diff --git a/api/client-server/definitions/sync_filter.yaml b/api/client-server/definitions/sync_filter.yaml index 65b18ba6f23..45a269c709d 100644 --- a/api/client-server/definitions/sync_filter.yaml +++ b/api/client-server/definitions/sync_filter.yaml @@ -47,7 +47,7 @@ properties: not_rooms: description: A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the ``'rooms'`` - filter. This filter is applied before the filters in ``ephemeral``, + filter. This filter is applied before the filters in ``ephemeral``, ``state``, ``timeline`` or ``account_data`` items: type: string @@ -73,33 +73,6 @@ properties: allOf: - $ref: room_event_filter.yaml description: The state events to include for rooms. - properties: - lazy_load_members: - type: boolean - description: |- - If ``true``, the only ``m.room.member`` events returned in - the ``state`` section of the ``/sync`` response are those - which are definitely necessary for a client to display - the ``sender`` of the timeline events in that response. - If ``false``, ``m.room.member`` events are not filtered. - By default, servers should suppress duplicate redundant - lazy-loaded ``m.room.member`` events from being sent to a given - client across multiple calls to ``/sync``, given that most clients - cache membership events (see ``include_redundant_members`` - to change this behaviour). - include_redundant_members: - type: boolean - description: |- - If ``true``, the ``state`` section of the ``/sync`` response will - always contain the ``m.room.member`` events required to display - the ``sender`` of the timeline events in that response, assuming - ``lazy_load_members`` is enabled. This means that redundant - duplicate member events may be returned across multiple calls to - ``/sync``. This is useful for naive clients who never track - membership data. If ``false``, duplicate ``m.room.member`` events - may be suppressed by the server across multiple calls to ``/sync``. - If ``lazy_load_members`` is ``false`` this field is ignored. - timeline: allOf: - $ref: room_event_filter.yaml From d56df3238c58abde17ca28165baa9b904cb743c0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 14:35:37 -0600 Subject: [PATCH 02/18] Generalize wording to fit /messages and /sync --- .../definitions/room_event_filter.yaml | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index fd399913294..5258ea30a9d 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -19,28 +19,32 @@ allOf: lazy_load_members: type: boolean description: |- - If ``true``, the only ``m.room.member`` events returned in - the ``state`` section of the ``/sync`` response are those - which are definitely necessary for a client to display - the ``sender`` of the timeline events in that response. + If ``true``, the only ``m.room.member`` events returned + are those which are definitely necessary for a client to + display the ``sender`` of the timeline events in the response. If ``false``, ``m.room.member`` events are not filtered. By default, servers should suppress duplicate redundant lazy-loaded ``m.room.member`` events from being sent to a given - client across multiple calls to ``/sync``, given that most clients + client across multiple calls, given that most clients cache membership events (see ``include_redundant_members`` to change this behaviour). + + Only applicable when filtering state events, such as the + ``state`` section of a ``/sync`` or ``/messages``. include_redundant_members: type: boolean description: |- - If ``true``, the ``state`` section of the ``/sync`` response will - always contain the ``m.room.member`` events required to display - the ``sender`` of the timeline events in that response, assuming - ``lazy_load_members`` is enabled. This means that redundant - duplicate member events may be returned across multiple calls to - ``/sync``. This is useful for naive clients who never track + If ``true``, response will always contain the ``m.room.member`` + events required to display the ``sender`` of the timeline events + in that response, assuming ``lazy_load_members`` is enabled. This + means that redundant duplicate member events may be returned across + multiple calls to. This is useful for naive clients who never track membership data. If ``false``, duplicate ``m.room.member`` events - may be suppressed by the server across multiple calls to ``/sync``. - If ``lazy_load_members`` is ``false`` this field is ignored. + may be suppressed by the server across multiple calls. If + ``lazy_load_members`` is ``false`` this field is ignored. + + Only applicable when filtering state events, such as the + ``state`` section of a ``/sync`` or ``/messages``. not_rooms: description: A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the ``'rooms'`` From 34d6c1f4ad60d7d753ac703613034a8756662ae8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 14:46:59 -0600 Subject: [PATCH 03/18] Clarify wording further for how to handle redundant members Note: This makes assumptions on what the TODO comment in Synapse means: https://github.com/matrix-org/synapse/blob/e26e6b3230f0b55376f0f3bf823dd789ac7064d0/synapse/handlers/pagination.py#L262 Due to lack of implementation, it is assumed that using the same filter across multiple calls to /sync OR /messages will result in the redundant members being excluded in the next request. For example, calling /sync, then /messages which returns some members, then /sync again will exclude the members due to them being in /messages. --- .../definitions/room_event_filter.yaml | 25 ++++++++++--------- api/client-server/message_pagination.yaml | 17 +++++++++++++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index 5258ea30a9d..35b3edf94c5 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -24,27 +24,28 @@ allOf: display the ``sender`` of the timeline events in the response. If ``false``, ``m.room.member`` events are not filtered. By default, servers should suppress duplicate redundant - lazy-loaded ``m.room.member`` events from being sent to a given - client across multiple calls, given that most clients - cache membership events (see ``include_redundant_members`` - to change this behaviour). + lazy-loaded ``m.room.member`` events from being sent to a + given client in a previous request using the same filter, + given that most clients cache membership events (see + ``include_redundant_members`` to change this behaviour). Only applicable when filtering state events, such as the - ``state`` section of a ``/sync`` or ``/messages``. + ``state`` section of a ``/sync`` or ``/messages`` response. include_redundant_members: type: boolean description: |- If ``true``, response will always contain the ``m.room.member`` events required to display the ``sender`` of the timeline events - in that response, assuming ``lazy_load_members`` is enabled. This - means that redundant duplicate member events may be returned across - multiple calls to. This is useful for naive clients who never track - membership data. If ``false``, duplicate ``m.room.member`` events - may be suppressed by the server across multiple calls. If - ``lazy_load_members`` is ``false`` this field is ignored. + in that response, assuming ``lazy_load_members`` is enabled. + This means that redundant duplicate member events will be returned + across multiple calls using the same filter. This is useful for + naive clients who never track membership data. If ``false`` or + not provided, duplicate ``m.room.member`` events should be + suppressed by the server across multiple calls. If ``lazy_load_members`` + is ``false`` this field is ignored. Only applicable when filtering state events, such as the - ``state`` section of a ``/sync`` or ``/messages``. + ``state`` section of a ``/sync`` or ``/messages`` response. not_rooms: description: A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the ``'rooms'`` diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 941e61fb9c3..ff6d970db98 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -108,6 +108,23 @@ paths: type: object title: RoomEvent "$ref": "definitions/event-schemas/schema/core-event-schema/room_event.yaml" + state: + type: array + description: |- + A list of state events relevant to showing the ``chunk``. For example, if + lazy-loading members is enabled in the filter then this will contain any + applicable membership events. Servers should be careful to not exclude + membership events which are older than ones already sent to the client. + Likewise, clients should be cautious and avoid using older membership + events as the current membership event when paginating backwards. + + Unless ``include_redundant_members`` is ``true``, the server should remove + redundant members which would have already been sent to clients in prior calls + to ``/messages`` or ``/sync`` with the same filter. + items: + type: object + title: RoomStateEvent + $ref: "definitions/event-schemas/schema/core-event-schema/state_event.yaml" examples: application/json: { "start": "t47429-4392820_219380_26003_2265", From b67161cf97badda0c37ccaa482634e5c5fa4093b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 14:59:59 -0600 Subject: [PATCH 04/18] List the endpoints which are lazy-loading aware --- api/client-server/definitions/room_event_filter.yaml | 9 +++++++-- api/client-server/event_context.yaml | 3 +++ api/client-server/message_pagination.yaml | 5 ++++- api/client-server/sync.yaml | 3 +++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index 35b3edf94c5..4790643e0a7 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -30,7 +30,12 @@ allOf: ``include_redundant_members`` to change this behaviour). Only applicable when filtering state events, such as the - ``state`` section of a ``/sync`` or ``/messages`` response. + ``state`` section of a lazy-loading aware endpoint. + + The endpoints which support lazy-loading are: + `/sync <#get-matrix-client-%CLIENT_RELEASE_LABEL%-sync>`_, + `/messages <#get-matrix-client-%CLIENT_RELEASE_LABEL%-rooms-roomid-messages>`_, + and `/context <#get-matrix-client-%CLIENT_RELEASE_LABEL%-rooms-roomid-context-eventid>`_. include_redundant_members: type: boolean description: |- @@ -45,7 +50,7 @@ allOf: is ``false`` this field is ignored. Only applicable when filtering state events, such as the - ``state`` section of a ``/sync`` or ``/messages`` response. + ``state`` section of a lazy-loading aware endpoint. not_rooms: description: A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the ``'rooms'`` diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index 91da3cf4f8f..c0f391e5298 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -34,6 +34,9 @@ paths: This API returns a number of events that happened just before and after the specified event. This allows clients to get the context surrounding an event. + + *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ + for more information. operationId: getEventContext security: - accessToken: [] diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index ff6d970db98..716afb659ae 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -33,6 +33,9 @@ paths: description: |- This API returns a list of message and state events for a room. It uses pagination query parameters to paginate history in the room. + + *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ + for more information. operationId: getRoomEvents security: - accessToken: [] @@ -120,7 +123,7 @@ paths: Unless ``include_redundant_members`` is ``true``, the server should remove redundant members which would have already been sent to clients in prior calls - to ``/messages`` or ``/sync`` with the same filter. + to lazy-loading aware endpoints with the same filter. items: type: object title: RoomStateEvent diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index f204152a082..87e7bf74d05 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -34,6 +34,9 @@ paths: Clients use this API when they first log in to get an initial snapshot of the state on the server, and then continue to call this API to get incremental deltas to the state, and to receive new messages. + + *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ + for more information. operationId: sync security: - accessToken: [] From ba520df004eafdf3fc58d051a567708d7419fe14 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 17:38:04 -0600 Subject: [PATCH 05/18] Move lazy loading to a section in Filtering --- .../definitions/room_event_filter.yaml | 36 ++++--------------- api/client-server/sync.yaml | 3 +- specification/client_server_api.rst | 33 +++++++++++++++++ 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index 4790643e0a7..0659be8e041 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -19,38 +19,16 @@ allOf: lazy_load_members: type: boolean description: |- - If ``true``, the only ``m.room.member`` events returned - are those which are definitely necessary for a client to - display the ``sender`` of the timeline events in the response. - If ``false``, ``m.room.member`` events are not filtered. - By default, servers should suppress duplicate redundant - lazy-loaded ``m.room.member`` events from being sent to a - given client in a previous request using the same filter, - given that most clients cache membership events (see - ``include_redundant_members`` to change this behaviour). - - Only applicable when filtering state events, such as the - ``state`` section of a lazy-loading aware endpoint. - - The endpoints which support lazy-loading are: - `/sync <#get-matrix-client-%CLIENT_RELEASE_LABEL%-sync>`_, - `/messages <#get-matrix-client-%CLIENT_RELEASE_LABEL%-rooms-roomid-messages>`_, - and `/context <#get-matrix-client-%CLIENT_RELEASE_LABEL%-rooms-roomid-context-eventid>`_. + If ``true``, enables lazy-loading of membership events. See + `Lazy-loading room members <#lazy-loading-room-members>`_ + for more information. Defaults to ``false``. include_redundant_members: type: boolean description: |- - If ``true``, response will always contain the ``m.room.member`` - events required to display the ``sender`` of the timeline events - in that response, assuming ``lazy_load_members`` is enabled. - This means that redundant duplicate member events will be returned - across multiple calls using the same filter. This is useful for - naive clients who never track membership data. If ``false`` or - not provided, duplicate ``m.room.member`` events should be - suppressed by the server across multiple calls. If ``lazy_load_members`` - is ``false`` this field is ignored. - - Only applicable when filtering state events, such as the - ``state`` section of a lazy-loading aware endpoint. + If ``true``, enables redudant membership events. Does not + apply unless ``lazy_load_members`` is ``true``. See + `Lazy-loading room members <#lazy-loading-room-members>`_ + for more information. Defaults to ``false``. not_rooms: description: A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the ``'rooms'`` diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 87e7bf74d05..bd659369cd8 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -36,7 +36,8 @@ paths: incremental deltas to the state, and to receive new messages. *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ - for more information. + for more information. Lazy-loading members is only supported on a ``StateFilter`` + for this endpoint. operationId: sync security: - accessToken: [] diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 604c2b1c699..a4b8dd5c084 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1268,6 +1268,39 @@ Filters can be created on the server and can be passed as as a parameter to APIs which return events. These filters alter the data returned from those APIs. Not all APIs accept filters. +Lazy-loading room members +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Membership events often take significant resources for clients to track. In an +effort to reduce the number of resources used, clients can enable "lazy-loading" +for room members. By doing this, servers will only ever send membership events +which are relevant to the client. + +In terms of filters, this means enabling ``lazy_load_members`` on a ``StateFilter`` +or ``RoomEventFilter``. When enabled, lazy-loading aware endpoints (see below) +will only include membership events for the ``sender`` of events being included +in the response. For example, if a client makes a ``/sync`` request with lazy-loading +enabled, the server will only return membership events for the ``sender`` of events +in the timeline, not all members of a room. + +Repeated calls to lazy-loading aware endpoints will result in redundant membership +events being excluded by default. Clients often track which membership events they +already have, therefore making the extra information not as useful to the client. +Clients can always request redundant members by setting ``include_redundant_members`` +to true in the filter. + +Servers should be cautious about which events they consider redundant. Membership +events can change over time, and should be included as relevant to maintain the +historical record. Likewise, clients should be cautious about treating an older event +as the current membership event for a user. + +.. Note:: + Repeated calls using the same filter to *any* lazy-loading aware endpoint may + result in redundant members being excluded from future calls. For example, a + request to ``/sync`` followed by a request to ``/messages`` may result in a + future call to ``/sync`` excluding members included by the ``/messages`` call. + + {{filter_cs_http_api}} Events From 7b266b33da0cdabcfa6e2d2fdf4d3fc36f83ed0f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 19:26:26 -0600 Subject: [PATCH 06/18] Add membership params Fixes https://github.com/matrix-org/matrix-doc/issues/1945 --- api/client-server/rooms.yaml | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/api/client-server/rooms.yaml b/api/client-server/rooms.yaml index cc1f2bf7e1d..acddf8916f5 100644 --- a/api/client-server/rooms.yaml +++ b/api/client-server/rooms.yaml @@ -288,6 +288,44 @@ paths: description: The room to get the member events for. required: true x-example: "!636q39766251:example.com" + - in: query + name: at + type: string + description: |- + The point in time (pagination token) to return members for in the room. + This token can be obtained from a ``prev_batch`` token returned for + each room by the sync API. Defaults to the current state of the room, + as determined by the server. + x-example: "YWxsCgpOb25lLDM1ODcwOA" + # XXX: As mentioned in MSC1227, replacing `[not_]membership` with a JSON + # filter might be a better alternative. + # See https://github.com/matrix-org/matrix-doc/issues/1337 + - in: query + name: membership + type: string + enum: + - join + - invite + - leave + - ban + description: |- + The kind of membership to filter for. Defaults to no filtering if + unspecified. When specified alongside ``not_membership``, the two + parameters create an 'or' condition: either the membership *is* + the same as ``membership`` **or** *is not* the same as ``not_membership``. + x-example: "join" + - in: query + name: not_membership + type: string + enum: + - join + - invite + - leave + - ban + description: |- + The kind of membership to exclude from the results. Defaults to no + filtering if unspecified. + x-example: leave security: - accessToken: [] responses: From b3d86f99b9d21ad98e26b37cf6afcc73d7064964 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 20:20:00 -0600 Subject: [PATCH 07/18] Add room summary spec --- api/client-server/sync.yaml | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index bd659369cd8..2c5042954c1 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -129,6 +129,50 @@ paths: title: Joined Room type: object properties: + summary: + title: RoomSummary + type: object + description: |- + Information about the room which clients may need to + correctly render it to users. + properties: + "m.heroes": + type: array + description: |- + The users which can be used to generate a room name + if the room does not have one. Required if the room + does not have a ``m.room.name`` or ``m.room.canonical_alias`` + state event with non-empty content. + + This should be the first 5 members of the room, ordered + by stream ordering, which are joined or invited. The + list must never include the client's own user ID. When + no joined or invited members are available, this should + consist of the banned and left users. More than 5 members + may be provided, however less than 5 should only be provided + when there are less than 5 members to represent. + + When lazy-loading room members is enabled, the membership + events for the heroes MUST be included in the ``state``, + unless they are redundant. When the list of users changes, + the server notifies the client by sending a fresh list of + heroes. If there are no changes since the last sync, this + field may be omitted. + items: + type: string + "m.joined_member_count": + type: integer + description: |- + The number of users with ``membership`` of ``join``, + including the client's own user ID. If this field has + not changed since the last sync, it may be omitted. + Required otherwise. + "m.invited_member_count": + type: integer + description: |- + The number of users with ``membership`` of ``invite``. + If this field has not changed since the last sync, it + may be omitted. Required otherwise. state: title: State type: object @@ -334,6 +378,14 @@ paths: "rooms": { "join": { "!726s6s6q:example.com": { + "summary": { + "m.heroes": [ + "@alice:example.com", + "@bob:example.com" + ], + "m.joined_member_count": 2, + "m.invited_member_count": 0 + }, "state": { "events": [ { From 8330810e957bf33991274b9fad6cd258deaf670d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 20:47:03 -0600 Subject: [PATCH 08/18] Specify the new room naming scheme --- specification/modules/instant_messaging.rst | 98 ++++++++------------- 1 file changed, 35 insertions(+), 63 deletions(-) diff --git a/specification/modules/instant_messaging.rst b/specification/modules/instant_messaging.rst index 86daa700657..dd3e9c6cf48 100644 --- a/specification/modules/instant_messaging.rst +++ b/specification/modules/instant_messaging.rst @@ -278,70 +278,42 @@ choose a name: #. If the room has an `m.room.canonical_alias`_ state event with a non-empty ``alias`` field, use the alias given by that field as the name. -#. If neither of the above conditions are met, a name should be composed based - on the members of the room. Clients should consider `m.room.member`_ events - for users other than the logged-in user, with ``membership: join`` or - ``membership: invite``. - - .. _active_members: - - i. If there is only one such event, the display name for the room should be - the `disambiguated display name`_ of the corresponding user. - - #. If there are two such events, they should be lexicographically sorted by - their ``state_key`` (i.e. the corresponding user IDs), and the display - name for the room should be the `disambiguated display name`_ of both - users: " and ", or a localised variant thereof. - - #. If there are three or more such events, the display name for the room - should be based on the disambiguated display name of the user - corresponding to the first such event, under a lexicographical sorting - according to their ``state_key``. The display name should be in the - format " and others" (or a localised variant thereof), where N - is the number of `m.room.member`_ events with ``membership: join`` or - ``membership: invite``, excluding the logged-in user and "user1". - - For example, if Alice joins a room, where Bob (whose user id is - ``@superuser:example.com``), Carol (user id ``@carol:example.com``) and - Dan (user id ``@dan:matrix.org``) are in conversation, Alice's - client should show the room name as "Carol and 2 others". - - .. TODO-spec - Sorting by user_id certainly isn't ideal, as IDs at the start of the - alphabet will end up dominating room names: they will all be called - "Arathorn and 15 others". Furthermore - user_ids are not necessarily - ASCII, which means we need to either specify a collation order, or specify - how to choose one. - - Ideally we might sort by the time when the user was first invited to, or - first joined the room. But we don't have this information. - - See https://matrix.org/jira/browse/SPEC-267 for further discussion. - -#. If the room has no valid ``m.room.name`` or ``m.room.canonical_alias`` - event, and no active members other than the current user, clients should - consider ``m.room.member`` events with ``membership: leave``. If such events - exist, a display name such as "Empty room (was and others)" (or - a localised variant thereof) should be used, following similar rules as for - active members (see `above `_). - -#. A complete absence of room name, canonical alias, and room members is likely - to indicate a problem with creating the room or synchronising the state - table; however clients should still handle this situation. A display name - such as "Empty room" (or a localised variant thereof) should be used in this - situation. - -.. _`disambiguated display name`: `Calculating the display name for a user`_ - -Clients SHOULD NOT use `m.room.aliases`_ events as a source for room names, as -it is difficult for clients to agree on the best alias to use, and aliases can -change unexpectedly. - -.. TODO-spec - How can we make this less painful for clients to implement, without forcing - an English-language implementation on them all? See - https://matrix.org/jira/browse/SPEC-425. +#. If neither of the above conditions are met, the client can optionally guess + an alias from the ``m.room.alias`` events in the room. This is a temporary + measure while clients do not promote canonical aliases as prominently. This + step may be removed in a future version of the specification. +#. If none of the above conditions are met, a name should be composed based + on the members of the room. Clients should consider `m.room.member`_ events + for users other than the logged-in user, as defined below. + + i. If the ``m.heroes`` for the room are greater or equal to + ``m.joined_member_count + m.invited_member_count - 1``, then use the + membership events for the heroes to calculate display names for the + users (`disambiguating them if required`_) and concatenating them. For + example, the client may choose to show "Alice, Bob, and Charlie + (@charlie:example.org)" as the room name. The client may optionally + limit the number + + #. If there are fewer heroes than ``m.joined_member_count + m.invited_member_count + - 1``, and ``m.joined_member_count + m.invited_member_count`` is greater + than 1, the client should use the heroes to calculate display names for + the users (`disambiguating them if required`_) and concatenating them + alongside a count of the remaining users. For example, "Alice, Bob, and + 1234 others". + + #. If ``m.joined_member_count + m.invited_member_count`` is less than or + equal to 1 (indicating the member is alone), the client should use the + rules above to indicate that the room was empty. For example, "Empty + Room (was Alice)", "Empty Room (was Alice and 1234 others)", or + "Empty Room" if there are no heroes. + +Clients SHOULD internationalise the room name to the user's language when using +the ``m.heroes`` to calculate the name. Clients SHOULD use minimum 5 heroes to +calculate room names where possible, but may use more or less to fit better with +their user experience. + +.. _`disambiguating them if required`: `Calculating the display name for a user`_ Forming relationships between events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From b1dccda49ddae41ec67e193b7da1f0bd1f345360 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 20:47:53 -0600 Subject: [PATCH 09/18] changelog --- changelogs/client_server/newsfragments/2035.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2035.feature diff --git a/changelogs/client_server/newsfragments/2035.feature b/changelogs/client_server/newsfragments/2035.feature new file mode 100644 index 00000000000..47029c280f2 --- /dev/null +++ b/changelogs/client_server/newsfragments/2035.feature @@ -0,0 +1 @@ +Add the option to lazy-load room members for increased client performance. From 3ade2a9ae78406c2804d57f4dbda09e0655bcb41 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 28 May 2019 13:56:25 -0600 Subject: [PATCH 10/18] List the endpoints which support LL --- specification/client_server_api.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index a4b8dd5c084..740023fb82c 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1300,6 +1300,11 @@ as the current membership event for a user. request to ``/sync`` followed by a request to ``/messages`` may result in a future call to ``/sync`` excluding members included by the ``/messages`` call. +The current endpoints which support lazy-loading room members are: + +* |/sync|_ +* |/rooms//messages|_ +* |/rooms/{roomId}/context/{eventId}|_ {{filter_cs_http_api}} From 551806a8ad797895a53f4555a252f1d59048ae43 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 28 May 2019 13:54:22 -0600 Subject: [PATCH 11/18] Add a reference to the filtering module to /sync --- api/client-server/sync.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 2c5042954c1..a9f1f714e1d 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -53,6 +53,8 @@ paths: requests. Creating a filter using the filter API is recommended for clients that reuse the same filter multiple times, for example in long poll requests. + + See `Filtering <#filtering>`_ for more information. x-example: "66696p746572" - in: query name: since From c5fdd5cb0bef008945cde2e915245ade190541c5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 28 May 2019 13:55:37 -0600 Subject: [PATCH 12/18] Change note style --- api/client-server/event_context.yaml | 2 +- api/client-server/message_pagination.yaml | 2 +- api/client-server/sync.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index c0f391e5298..327c8f43fc7 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -35,7 +35,7 @@ paths: after the specified event. This allows clients to get the context surrounding an event. - *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ + *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_ for more information. operationId: getEventContext security: diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 716afb659ae..8469eec4b67 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -34,7 +34,7 @@ paths: This API returns a list of message and state events for a room. It uses pagination query parameters to paginate history in the room. - *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ + *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_ for more information. operationId: getRoomEvents security: diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index a9f1f714e1d..4fe22d50844 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -35,7 +35,7 @@ paths: of the state on the server, and then continue to call this API to get incremental deltas to the state, and to receive new messages. - *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ + *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_ for more information. Lazy-loading members is only supported on a ``StateFilter`` for this endpoint. operationId: sync From afead2eb1bb578d6ca01af3ed3a8f729b852e795 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 14:18:41 -0600 Subject: [PATCH 13/18] Clarify LL in /sync a bit more --- api/client-server/sync.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 4fe22d50844..a0d2fd60039 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -37,7 +37,13 @@ paths: *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_ for more information. Lazy-loading members is only supported on a ``StateFilter`` - for this endpoint. + for this endpoint. When lazy-loading is enabled, servers MUST include the + syncing user's own membership event when they join a room, or when the + full state of rooms is requested. The user's own membership event is eligible + for being considered redudant by the server. When a sync is ``limited``, + the server MUST return membership events for the timeline, even if the + applicable events are not in the response, regardless as to whether or not + they are redundant. operationId: sync security: - accessToken: [] From 77c4c4b07cb1cfe30d7a3477944eb2229e62ab2f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 08:27:18 -0600 Subject: [PATCH 14/18] Add general clarity --- api/client-server/definitions/room_event_filter.yaml | 2 +- api/client-server/sync.yaml | 9 +++++---- specification/client_server_api.rst | 3 +++ specification/modules/instant_messaging.rst | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index 0659be8e041..7045396d82a 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -25,7 +25,7 @@ allOf: include_redundant_members: type: boolean description: |- - If ``true``, enables redudant membership events. Does not + If ``true``, enables redundant membership events. Does not apply unless ``lazy_load_members`` is ``true``. See `Lazy-loading room members <#lazy-loading-room-members>`_ for more information. Defaults to ``false``. diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index a0d2fd60039..ed9d74206bf 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -40,10 +40,11 @@ paths: for this endpoint. When lazy-loading is enabled, servers MUST include the syncing user's own membership event when they join a room, or when the full state of rooms is requested. The user's own membership event is eligible - for being considered redudant by the server. When a sync is ``limited``, - the server MUST return membership events for the timeline, even if the - applicable events are not in the response, regardless as to whether or not - they are redundant. + for being considered redundant by the server. When a sync is ``limited``, + the server MUST return membership events for events in the gap (from ``since``), + even if the applicable events are not in the response, regardless as to whether + or not they are redundant. ``include_redundant_members`` is ignored for limited + syncs. operationId: sync security: - accessToken: [] diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 740023fb82c..5290ec2005c 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1306,6 +1306,9 @@ The current endpoints which support lazy-loading room members are: * |/rooms//messages|_ * |/rooms/{roomId}/context/{eventId}|_ +API endpoints +~~~~~~~~~~~~~ + {{filter_cs_http_api}} Events diff --git a/specification/modules/instant_messaging.rst b/specification/modules/instant_messaging.rst index dd3e9c6cf48..c514f48131b 100644 --- a/specification/modules/instant_messaging.rst +++ b/specification/modules/instant_messaging.rst @@ -293,7 +293,7 @@ choose a name: users (`disambiguating them if required`_) and concatenating them. For example, the client may choose to show "Alice, Bob, and Charlie (@charlie:example.org)" as the room name. The client may optionally - limit the number + limit the number of users it uses to generate a room name. #. If there are fewer heroes than ``m.joined_member_count + m.invited_member_count - 1``, and ``m.joined_member_count + m.invited_member_count`` is greater From a0e82018161f82a723e2d57eb3e14eec42d66610 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 08:27:53 -0600 Subject: [PATCH 15/18] Apply suggestions from code review Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- api/client-server/event_context.yaml | 2 +- api/client-server/message_pagination.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index 327c8f43fc7..0e7fa531f68 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -35,7 +35,7 @@ paths: after the specified event. This allows clients to get the context surrounding an event. - *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_ + *Note*: This endpoint supports lazy-loading of room member events. See `Filtering <#lazy-loading-room-members>`_ for more information. operationId: getEventContext security: diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 8469eec4b67..c5d7b8fc47d 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -34,7 +34,7 @@ paths: This API returns a list of message and state events for a room. It uses pagination query parameters to paginate history in the room. - *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_ + *Note*: This endpoint supports lazy-loading of room member events. See `Filtering <#lazy-loading-room-members>`_ for more information. operationId: getRoomEvents security: From e4339fd68755344527cce85895ac131ee8618e6e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 09:01:14 -0600 Subject: [PATCH 16/18] More clarity --- specification/client_server_api.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 5290ec2005c..c62740d475d 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1276,12 +1276,12 @@ effort to reduce the number of resources used, clients can enable "lazy-loading" for room members. By doing this, servers will only ever send membership events which are relevant to the client. -In terms of filters, this means enabling ``lazy_load_members`` on a ``StateFilter`` -or ``RoomEventFilter``. When enabled, lazy-loading aware endpoints (see below) -will only include membership events for the ``sender`` of events being included -in the response. For example, if a client makes a ``/sync`` request with lazy-loading -enabled, the server will only return membership events for the ``sender`` of events -in the timeline, not all members of a room. +In terms of filters, this means enabling ``lazy_load_members`` on a ``RoomEventFilter`` +(or a ``StateFilter`` in the case of ``/sync`` only). When enabled, lazy-loading +aware endpoints (see below) will only include membership events for the ``sender`` +of events being included in the response. For example, if a client makes a ``/sync`` +request with lazy-loading enabled, the server will only return membership events +for the ``sender`` of events in the timeline, not all members of a room. Repeated calls to lazy-loading aware endpoints will result in redundant membership events being excluded by default. Clients often track which membership events they From a38af2009f72fc91f3aa4a90a323a050ba8dde06 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 10:37:57 -0600 Subject: [PATCH 17/18] Apply suggestions from code review Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- api/client-server/message_pagination.yaml | 6 +++--- api/client-server/sync.yaml | 4 ++-- specification/client_server_api.rst | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index c5d7b8fc47d..3e01437abb6 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -115,14 +115,14 @@ paths: type: array description: |- A list of state events relevant to showing the ``chunk``. For example, if - lazy-loading members is enabled in the filter then this will contain any - applicable membership events. Servers should be careful to not exclude + ``lazy_load_members`` is enabled in the filter then this will contain any + the membership events for the the senders of events in the ``chunk``. Servers should be careful to not exclude membership events which are older than ones already sent to the client. Likewise, clients should be cautious and avoid using older membership events as the current membership event when paginating backwards. Unless ``include_redundant_members`` is ``true``, the server should remove - redundant members which would have already been sent to clients in prior calls + membership events which would have already been sent to clients in prior calls to lazy-loading aware endpoints with the same filter. items: type: object diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index ed9d74206bf..45829f6874b 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -41,8 +41,8 @@ paths: syncing user's own membership event when they join a room, or when the full state of rooms is requested. The user's own membership event is eligible for being considered redundant by the server. When a sync is ``limited``, - the server MUST return membership events for events in the gap (from ``since``), - even if the applicable events are not in the response, regardless as to whether + the server MUST return membership events for events in the gap (between ``since`` and the start of the returned timeline), + regardless as to whether or not they are redundant. ``include_redundant_members`` is ignored for limited syncs. operationId: sync diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index c62740d475d..42f3484974e 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1286,7 +1286,7 @@ for the ``sender`` of events in the timeline, not all members of a room. Repeated calls to lazy-loading aware endpoints will result in redundant membership events being excluded by default. Clients often track which membership events they already have, therefore making the extra information not as useful to the client. -Clients can always request redundant members by setting ``include_redundant_members`` +Clients can always request redundant membership events by setting ``include_redundant_members`` to true in the filter. Servers should be cautious about which events they consider redundant. Membership @@ -1296,9 +1296,9 @@ as the current membership event for a user. .. Note:: Repeated calls using the same filter to *any* lazy-loading aware endpoint may - result in redundant members being excluded from future calls. For example, a + result in redundant membership events being excluded from future calls. For example, a request to ``/sync`` followed by a request to ``/messages`` may result in a - future call to ``/sync`` excluding members included by the ``/messages`` call. + future call to ``/sync`` excluding membership events returned by the ``/messages`` call. The current endpoints which support lazy-loading room members are: From 0506d09cf7735ac01ffe30e1783cd0429a761c28 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 10 Jun 2019 19:38:44 +0100 Subject: [PATCH 18/18] incorporate LL review from matthew --- .../definitions/room_event_filter.yaml | 3 +- api/client-server/message_pagination.yaml | 14 ++-- api/client-server/sync.yaml | 19 +++--- specification/client_server_api.rst | 67 ++++++++++++------- specification/modules/instant_messaging.rst | 2 +- 5 files changed, 63 insertions(+), 42 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index 7045396d82a..880cb173bd7 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -25,7 +25,8 @@ allOf: include_redundant_members: type: boolean description: |- - If ``true``, enables redundant membership events. Does not + If ``true``, sends all membership events for all events, even if they have already + been sent to the client. Does not apply unless ``lazy_load_members`` is ``true``. See `Lazy-loading room members <#lazy-loading-room-members>`_ for more information. Defaults to ``false``. diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 3e01437abb6..35555375c3f 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -115,15 +115,13 @@ paths: type: array description: |- A list of state events relevant to showing the ``chunk``. For example, if - ``lazy_load_members`` is enabled in the filter then this will contain any - the membership events for the the senders of events in the ``chunk``. Servers should be careful to not exclude - membership events which are older than ones already sent to the client. - Likewise, clients should be cautious and avoid using older membership - events as the current membership event when paginating backwards. + ``lazy_load_members`` is enabled in the filter then this may contain + the membership events for the senders of events in the ``chunk``. - Unless ``include_redundant_members`` is ``true``, the server should remove - membership events which would have already been sent to clients in prior calls - to lazy-loading aware endpoints with the same filter. + Unless ``include_redundant_members`` is ``true``, the server + may remove membership events which would have already been + sent to the client in prior calls to this endpoint, assuming + the membership of those members has not changed. items: type: object title: RoomStateEvent diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 45829f6874b..00ed562d012 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -39,12 +39,15 @@ paths: for more information. Lazy-loading members is only supported on a ``StateFilter`` for this endpoint. When lazy-loading is enabled, servers MUST include the syncing user's own membership event when they join a room, or when the - full state of rooms is requested. The user's own membership event is eligible + full state of rooms is requested, to aid discovering the user's avatar & + displayname. + + Like other members, the user's own membership event is eligible for being considered redundant by the server. When a sync is ``limited``, - the server MUST return membership events for events in the gap (between ``since`` and the start of the returned timeline), - regardless as to whether - or not they are redundant. ``include_redundant_members`` is ignored for limited - syncs. + the server MUST return membership events for events in the gap + (between ``since`` and the start of the returned timeline), regardless + as to whether or not they are redundant. This ensures that joins/leaves + and profile changes which occur during the gap are not lost. operationId: sync security: - accessToken: [] @@ -149,9 +152,9 @@ paths: type: array description: |- The users which can be used to generate a room name - if the room does not have one. Required if the room - does not have a ``m.room.name`` or ``m.room.canonical_alias`` - state event with non-empty content. + if the room does not have one. Required if the room's + ``m.room.name`` or ``m.room.canonical_alias`` state events + are unset or empty. This should be the first 5 members of the room, ordered by stream ordering, which are joined or invited. The diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 42f3484974e..a292eaeb01d 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1273,32 +1273,51 @@ Lazy-loading room members Membership events often take significant resources for clients to track. In an effort to reduce the number of resources used, clients can enable "lazy-loading" -for room members. By doing this, servers will only ever send membership events +for room members. By doing this, servers will attempt to only send membership events which are relevant to the client. -In terms of filters, this means enabling ``lazy_load_members`` on a ``RoomEventFilter`` -(or a ``StateFilter`` in the case of ``/sync`` only). When enabled, lazy-loading -aware endpoints (see below) will only include membership events for the ``sender`` -of events being included in the response. For example, if a client makes a ``/sync`` -request with lazy-loading enabled, the server will only return membership events -for the ``sender`` of events in the timeline, not all members of a room. - -Repeated calls to lazy-loading aware endpoints will result in redundant membership -events being excluded by default. Clients often track which membership events they -already have, therefore making the extra information not as useful to the client. -Clients can always request redundant membership events by setting ``include_redundant_members`` -to true in the filter. - -Servers should be cautious about which events they consider redundant. Membership -events can change over time, and should be included as relevant to maintain the -historical record. Likewise, clients should be cautious about treating an older event -as the current membership event for a user. - -.. Note:: - Repeated calls using the same filter to *any* lazy-loading aware endpoint may - result in redundant membership events being excluded from future calls. For example, a - request to ``/sync`` followed by a request to ``/messages`` may result in a - future call to ``/sync`` excluding membership events returned by the ``/messages`` call. +It is important to understand that lazy-loading is not intended to be a +perfect optimisation, and that it may not be practical for the server to +calculate precisely which membership events are relevant to the client. As a +result, it is valid for the server to send redundant membership events to the +client to ease implementation, although such redundancy should be minimised +where possible to conserve bandwidth. + +In terms of filters, lazy-loading is enabled by enabling ``lazy_load_members`` +on a ``RoomEventFilter`` (or a ``StateFilter`` in the case of ``/sync`` only). +When enabled, lazy-loading aware endpoints (see below) will only include +membership events for the ``sender`` of events being included in the response. +For example, if a client makes a ``/sync`` request with lazy-loading enabled, +the server will only return membership events for the ``sender`` of events in +the timeline, not all members of a room. + +When processing a sequence of events (e.g. by looping on ``/sync`` or +paginating ``/messages``), it is common for blocks of events in the sequence +to share a similar set of senders. Rather than responses in the sequence +sending duplicate membership events for these senders to the client, the +server MAY assume that clients will remember membership events they have +already been sent, and choose to skip sending membership events for members +whose membership has not changed. These are called 'redundant membership +events'. Clients may request that redundant membership events are always +included in responses by setting ``include_redundant_members`` to true in the +filter. + +The expected pattern for using lazy-loading is currently: + +* Client performs an initial /sync with lazy-loading enabled, and receives + only the membership events which relate to the senders of the events it + receives. +* Clients which support display-name tab-completion or other operations which + require rapid access to all members in a room should call /members for the + currently selected room, with an ``?at`` parameter set to the /sync + response's from token. The member list for the room is then maintained by + the state in subsequent incremental /sync responses. +* Clients which do not support tab-completion may instead pull in profiles for + arbitrary users (e.g. read receipts, typing notifications) on demand by + querying the room state or ``/profile``. + +.. TODO-spec + This implies that GET /state should also take an ``?at`` param The current endpoints which support lazy-loading room members are: diff --git a/specification/modules/instant_messaging.rst b/specification/modules/instant_messaging.rst index c514f48131b..679eabdc6db 100644 --- a/specification/modules/instant_messaging.rst +++ b/specification/modules/instant_messaging.rst @@ -287,7 +287,7 @@ choose a name: on the members of the room. Clients should consider `m.room.member`_ events for users other than the logged-in user, as defined below. - i. If the ``m.heroes`` for the room are greater or equal to + i. If the number of ``m.heroes`` for the room are greater or equal to ``m.joined_member_count + m.invited_member_count - 1``, then use the membership events for the heroes to calculate display names for the users (`disambiguating them if required`_) and concatenating them. For