-
-
Notifications
You must be signed in to change notification settings - Fork 99
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
/sync API does not tell clients when the server's view of state changes outside the timeline #1209
Comments
You're not using the term "reset" in the same way as we have been doing elsewhere. We've been using "state reset" to refer to matrix-org/synapse#1953, which is normally where an attempt to resolve a recent room state against a quite old one causes a whole cascade of changes to the current room state with the net effect that much (but not all!) of the room state ends up back where it was a few months ago. So a state reset is one reason that clients can get out of sync, but in general any state conflict resolution (such as the one in your diagram above) can result in a change in room state which we don't currently tell clients about. |
this is a spec issue really; moving it over. |
oh bother. It's really not. |
why not? i don't think the spec says how to handle this? |
The API for AFAIK it should be possible for a server to say "whoops, this state is wrong, and this state is right" and put it under the https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-sync |
This is overall pretty catastrophic from a UX perspective when this happens, and makes me feel Matrix is super flakey. I encountered this from a state reset in a v1 room, which meant I was kicked but it was still present as joined in riot-web, and I couldn't leave it because I wasn't in the room :/ but this issue is applicable for any kind of fork in room state and so we will likely keep hitting edge cases manifesting as crap UX until we fix this. |
@kegsay Related, in that case: matrix-org/synapse#1597 |
Except that entries in
not that I'm aware of, no. |
@joepie91 thanks for this. It really depends on how we wish to communicate state conflicts to clients. We probably don't want to flood the timeline with state changes because the state res algo decided to kick in and pretend a bunch of previously sent state is no longer valid. This is why I'm suggesting it should reside in matrix-org/synapse#1597 is mainly complaining that the spec says this should be impossible. It might be worth killilng two birds with one stone and saying "hey, under these circumstances, you may get them to appear twice (byte-for-byte identical)" so clients have some way of realising that something weird is going on. |
I would propose we just used the previous state which we already track under |
the proposal sounds reasonable, but it's obscure enough that I think if we're going to do it, it needs to end up in the spec. |
incidentally, there is another glitch here. The It may be close enough, or we may need to work around it by (say) forcing a gappy sync. |
Is this the current iteration of the Hotel California issue force joining users who have left back to Matrix HQ and Element Android rooms amongst others? |
AFAICS this is a spec (protocol-level) defect rather than Synapse per-se. FWIW I've heard indirectly that sliding sync will fix this. |
it is, and I really don't know why I moved it back to this repo. Let's move it again. |
It's worth noting that faster joins introduce a new way that clients can end up with "incorrect" state: it's possible for us to accept events that we shouldn't (or vice versa) during the "background resync" phase, and then we have no way to tell clients when we change our minds. |
It's worth noting that Sliding Sync provides a mechanism for telling clients about the updated state without inserting events into the timeline. It does this by:
The intended flow here would be:
{
rooms: {
"!reset:room": {
required_state: [
{ type: "m.room.member", state_key: "@alice:example.com", ... }
]
}
}
} or: {
rooms: {
"!reset:room": {
initial: true,
name: "Reset Room",
required_state: [
{ type: "m.room.member", state_key: "@alice:example.com", ... },
{ type: "m.room.member", state_key: "@bob:example.com", ... },
{ type: "m.room.name", state_key: "", ... },
{ type: "m.room.create", state_key: "", ... },
{ type: "m.room.power_levels", state_key: "", ... },
...
],
timeline: [ ... ]
}
}
} |
If the state graph forks and then merges again, some state events may be reset if they are in conflict. For instance:
The fact the bob kicked alice on one branch of the DAG may arrive late, causing alice's topic2 to be considered as reverted for the room's state going forwards. We currently do not tell clients via /sync that this has happened however, so the client's view of the room state will drift until they entirely resync (e.g. by flushing your cache in Riot).
Instead, we need a way of re-issuing the 'topic1' event into the state block in the /sync response to tell clients about the reset. This is potentially problematic as state changes like this may happen at any point in the timeline, whereas we only snapshot state at the beginning of a sync response. (However, if we include inlined state changes in the timeline at the 'right' point, perhaps this is enough?)
The text was updated successfully, but these errors were encountered: