-
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
MSC2108: Sync over Server Sent Events #2108
base: old_master
Are you sure you want to change the base?
Conversation
Cool! will do in few hours |
Signed-off-by: Sergii <sergiy.stotskiy@gmail.com>
Added |
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.
Idea sounds quite neat but more clarifications are needed in the doc.
* instead of using the `since` query parameter, the next batch token will be passed through the `Last-Event-ID` header. | ||
* each event will have the same format as what `/sync` returns. The id of each event will be the `next_batch` token | ||
* the server sends events in exactly the same way that it would send responses to `/sync` calls with the `since` | ||
parameter set to the previous `next_batch` |
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.
As per above, perhaps you could give a description on what an event is in SSE terms? I assume a SSE event is the body being sent along the wire, but it's not explicit here.
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.
Added links to documentation for the shape of matrix sync endpoint and for the format of SSE event.
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.
It still doesn't make any sense to me: how is a client meant to resume their sync stream? All they'd have is a Last-Event-ID
and a filter.
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.
If their call to /sync/sse
gets killed, then they just make a new call, with the Last-Event-ID
header set to the last SSE event ID that it saw.
It may be helpful to give an example of how the requests/responses look, so that people don't have to go digging through the SSE docs.
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.
+1 to examples. The SSE docs are a bit too complicated to try and parse in parallel here. Doesn't even need to be valid SSE:
GET /_matrix/client/r0/sync/sse
Last-Event-ID: 12
{"sync": "response_here"}
Relates to #2024
I looked through the changelog of Client-Server communication but cannot find any information of why In terms of SSE, it make sense to publish new events to clients as soon as changes are applied by homeserver, so I guess that most of the times almost all fields of So, right now I have doubts whether it make sense to reuse the payload format of |
Any news? |
I'd guess that it's because
I don't think it should be too bad, because all of the top-level items (except for |
Is there something else I can do to move this forward? Or may I start playing with implementation? |
but instead propose to use a different underlying technology to do this. So: | ||
* lets expose `/sync/sse` URL for SSE in order to be backward compatible with other clients and servers | ||
* this URL returns the same data as continually calling `/sync` | ||
* it accepts the same parameters as `/sync`, except `since` and `timeout` |
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.
how does set_presence
work in this proposal?
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.
Good question. My guess is that it would be equivalent to continually calling /sync
with the same set_presence
parameter, for as long as the SSE connection is alive. When the SSE connection dies, then the behaviour would be the same as a client no longer calling /sync
. Maybe this should be made more explicit.
but instead propose to use a different underlying technology to do this. So: | ||
* lets expose `/sync/sse` URL for SSE in order to be backward compatible with other clients and servers | ||
* this URL returns the same data as continually calling `/sync` | ||
* it accepts the same parameters as `/sync`, except `since` and `timeout` |
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.
how does full_state
work in this proposal?
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.
Good question. I think that there are three options:
- drop
full_state
for SSE. If a client wants to dofull_state
, they can call/sync
to start with, and then continue the sync using SSE. - only return the full state for the first SSE event, and incremental state for subsequent SSE events
- return the full state for event SSE event. The first SSE event gets sent immediately (as it would when calling
/sync
withfull_state
), but subsequent SSE events only get sent when there's actually something new
Personally, I think my preference would be 2, then 1, then 3, with 1 and 2 being fairly close, and 3 being much less preferred.
So, instead of long polling I propose to implement | ||
sync logic over [Server Sent Events][mdn-sse](SSE) | ||
|
||
## Proposal |
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.
There's no mention of how limited syncs work in this proposal. Syncs can be limited due to a filter or due to the server's maximum willingness to serve events.
The existing sync endpoint is built for long polling, which doesn't really make it suitable for SSE. Although the sync format does lend itself to being a nice and backwards compatible data structure, I think it would be best if we used a more stream-oriented structure for SSE.
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.
My thought on this was that it would work just like calling /sync
repeatedly. For example, if you call /sync/sse
with the Last-Event-ID
set to some value, and the equivalent /sync
call would have return a limited sync, then the first SSE event that you get will also be a limited result. Also, if the server is streaming SSE events, and you suddenly get a billion events in one room, then the next SSE event that it sends will be limited. It doesn't quite fit perfectly with a streaming model (for example, calling /sync/sse
with the same Last-Event-ID
two times won't give you the same result for the first event), but it fits with the way that Matrix currently handles truncating results. And I don't think SSE has a native method of skipping over events.
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.
Again, adding some examples to the proposal may be useful.
@stalniy: typically review takes a lot longer than we'd like. Implementations help prove that a MSC is needed and serves a purpose, however at this early stage in the proposal process it doesn't make much sense to engineer a perfect implementation. Something which shows the idea as a proposal aide is certainly worthwhile, given the complexity of this proposal (ie: a plain HTML+JS page which dumps JSON bodies into the DOM as a demo). A proper implementation demonstration is required later in the proposal stages. For the time being, it's best to bring it up every couple months in #matrix-spec:matrix.org to try and solicit review. |
Just to add a little note here as well, I decided to write my own little personal testbed for a Server-Sent Events backend as a separate little middleware server in Ruby. It should fit in beside a regular Synapse instance, and just requires a reverse proxy to route |
Any updates? This would be a very important feature to have, especially for mobile users or areas with very spotty internet connection where a multitude of requests actually hurts performance quite a lot. |
This proposal needs to be updated in order to be reviewed again. I’m currently working on my open source project and don’t have time to fix this. @IngwiePhoenix you can join and help to fix all suggestions and merge back in my repo so we can continue discussion in the same PR. |
@stalniy @IngwiePhoenix is there a possibility this MSC will be picked back up? If not, do any of you two know how we can push this MSC forward? I think there'd be a lot of interest for this. |
An extension to MSC 3079 to support WebSockets may be an alternative to this proposal. It requires more client and server work, but saves far more bandwidth than this proposal can hope to. Servers can use a proxy initially (so it doesn't help server resources too much) and clients can use HTTP shims/interceptors. |
I’ll try to find some time in the next few weeks to update this. However, I’m not a Python expert so would be cool if somebody could implement it eventually |
I volunteer, I've been working with the synapse codebase for a little while, MXID is |
Awesome! @ShadowJonathan I will ping you when this proposal settles down. |
Are there any news on the topic? |
@anoadragon453 I'd personally like to see this MSC (or a followup MSC) transition to "Sliding Sync over Server Sent Events", since there are quite a few places where there is native support for SSE for event streams, which offer both performance and power usage improvements over repeating application-triggered requests. Android being one such example. |
I have no clue whether that's true; but in my opinion, reducing battery usage of Element-Android (while providing instant notifications, without involving Google or other 3rd parties and points of failure) should be considered most important. |
@ananace Indeed. It's worth noting that the Sliding Sync MSC explains why it proposes HTTP long-polling over WebSockets (or SSE) which is simply that it's more of an incremental change for today's implementations to transition from Sync v2. However the MSC also states that the design of the proposal makes it easy to transition to a WebSockets implementation in the future after Sliding Sync is implemented, which is true. I think it'd be slightly more of a leap to SSE, as SSE doesn't define methods for clients to communicate back to the server. In Sliding Sync, the client is constantly asking for specific data (the messages in the room I'm currently looking at, the rooms I can currently see on my screen, etc.) and this information is constantly updating. So I think you'd end up with SSE + an endpoint the client would keep hitting to get the server to send down different events. And that doesn't seem all that different from the bi-directional pipe that WebSockets provides though. The document does mention some other advantages to SSE; I'm not sure how much weight those have. |
@mcg-matrix None of this will help you if your Element Android client is in the background and your phone has stopped the process. You still need push notifications to get instant notifications. Check out https://unifiedpush.org/ if you'd like a push solution that doesn't involve Google and is supported by Element Android and other applications. |
@anoadragon453 Yeah, an SSE version of sliding sync would be a very different beast from an SSE version of current sync. I had some design ideas on the subject when in other discussions of MSC3575, and I still think it'd be useful as a transport - just maybe not for the most general use-case. |
Sounds obvious. :-) I was not trying to find a way out of such a situation.
Thanks, I had heard of UnifiedPush; I wouldn't like any 3rd party or point of failure in addition to Element + Homeserver for my users. |
Fixes matrix-org/matrix-spec#475
full proposal
Introduction
Currently, Matrix clients use long polling to get the latest state from the server, it becomes an issue when you have a lot of clients because:
So, instead of long polling I propose to implement sync logic over Server Sent Events(SSE)
Proposal
Server Sent Events(SSE) is a way for servers to push events to clients. It was a part of HTML5 standard and now available in all major web and mobile browsers.
It was specifically designed to overcome challenges related to short/long polling. By introducing this technology, we can get the next benefits:
Last-Event-Id
header out of the box