-
Notifications
You must be signed in to change notification settings - Fork 385
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
[WIPish] MSC1776: Implementing peeking via /sync #1776
Changes from all commits
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,145 @@ | ||
# MSC1776: Proposal for implementing peeking via /sync in the CS API | ||
|
||
## Problem | ||
|
||
Peeking into rooms without joining them currently relies on the deprecated v1 | ||
/initialSync and /events APIs. | ||
|
||
This poses the following issues: | ||
|
||
* Servers and clients must implement two separate sets of event-syncing logic, | ||
doubling complexity. | ||
* Peeking a room involves setting a stream of long-lived /events requests going. | ||
Having multiple streams is racey, competes for resources with the /sync stream, | ||
and doesn't scale given each room requires a new /events stream. | ||
|
||
## Solution | ||
|
||
We extend /sync to support peeking into rooms on demand. | ||
|
||
This can be done as part of extending /sync to also support paginating results | ||
per-room, which is desirable for reducing the size of initial /syncs and making | ||
them more granular, in order to speed up login. | ||
|
||
Proposal: we add a POST form of /sync, which lets the user add/remove additional | ||
filters on the fly in order to aid peeking into specific sets of rooms with | ||
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. This feels like implementing joins via filters, without actually joining. I can't help but feel this is really changing the whole meaning of filters, which (at least the name implies) filters a large set of data into a smaller set. |
||
specific filters. Filtering on rooms which you are not joined to is considered | ||
a request to peek. We also let it support paginating results by grouping them | ||
into batches of rooms. | ||
|
||
**Conceptually** this could look like something like: | ||
```json | ||
POST /sync | ||
{ | ||
"filters": [ | ||
"normal sync filter (limit results to 10 rooms at a time)", | ||
"peek just m.flair on this set of rooms (to discover flair for users)" | ||
"peek full room that we're previewing", | ||
"peek full room a profile-room we're looking at", | ||
"peek just m.room.{name,avatar}, m.subgroup on this set of rooms (to display groups-as-rooms)", | ||
], | ||
"pagination": { | ||
"room_limit": 10 | ||
} | ||
} | ||
``` | ||
|
||
The `pagination` field would support two fields: | ||
* `room_limit` (which limits the number of rooms returned in a given /sync | ||
response) parameter | ||
* `room_order` (a constant that defines the ordering of the rooms within a /sync | ||
response. only "m.origin_ts" would be defined). | ||
|
||
To avoid the hassle of manually maintaining filters, the act of specifying a | ||
filter could automatically memoize it on the server so that it can be | ||
efficiently referred to in future. (The resulting filter ID could be returned | ||
in the /sync response). | ||
|
||
So, **concretely**, this would look something like: | ||
|
||
```json | ||
POST /sync | ||
{ | ||
"filters": [ | ||
{ | ||
"room": { | ||
"state": { | ||
"lazy_load_members": true | ||
}, | ||
"timeline": { | ||
"limit": 20 | ||
}, | ||
} | ||
}, | ||
{ | ||
"room": { | ||
"rooms": [ | ||
"!pr0file1:example.com", | ||
"!pr0file2:example.com", | ||
"!pr0file3:example.com", | ||
], | ||
"state": { | ||
"types": [ | ||
"m.flair" | ||
] | ||
} | ||
} | ||
}, | ||
], | ||
"paginate": { | ||
"room_limit": 10 | ||
} | ||
} | ||
``` | ||
|
||
...to request a sync which gives us both the normal timeline, as well as peek | ||
changes in flair events for 3 users we're stalking because they're in the timeline | ||
currently displayed on screen. | ||
|
||
In case of receiving large sync responses (initial or catchup sync), we request | ||
them to be batched with no more than 10 rooms per response. | ||
|
||
The sync response would include: | ||
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 might be blind, but where would the room contents be seen in the sync response. In timeline? Would there be any meaningful way to determine if we are truly joined to them without knowing the filter? |
||
|
||
```json | ||
{ | ||
"filter_ids": [123, 124] | ||
} | ||
``` | ||
|
||
...to give the user the IDs of the filter objects which were implicitly created | ||
from the POST, so that they can be reused in subsequent invocations of /sync | ||
directly. Alternatively, the filter IDs could be encoded into the sync token so | ||
that subsequent `GET /sync` did the right thing without needing to restate the | ||
filters. | ||
|
||
## Hybrid sync | ||
|
||
This pattern also enables "hybrid sync" (proposed during the June 2018 | ||
brainstorm with Manu/Erik/Matthew and others when considering how to speed up | ||
initial sync), in that a slow large granular incremental sync could be | ||
interrupted and later resumed in order to prioritise loading specific rooms as | ||
the user navigates the app. | ||
|
||
## Tradeoffs | ||
|
||
The API shape here is picked quite naively as it seems to do the job. There are | ||
probably many other ways to skin the cat. | ||
|
||
## Security considerations | ||
|
||
Need to worry about clients DoSing by requesting overly unpleasant filters? | ||
|
||
## Issues | ||
|
||
How do we represent peek failures? | ||
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. Pass a leave/ban event for |
||
|
||
## Dependencies | ||
|
||
This unblocks MSC1769 (profiles as rooms) and MSC1772 (groups as rooms) | ||
This depends on MSC1777 (peeking over federation) to work well in practice. | ||
|
||
## History | ||
|
||
This takes some inspiration from Erik's original 'paginated sync' PR to Synapse | ||
from 2016: https://github.com/matrix-org/synapse/pull/893/files |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Devil's advocate: why not a PUT version of https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-user-userid-filter-filterid ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might need a new section for "peek these rooms please"