|Neil Alexander 464b908bd0||3 months ago|
|consumers||4 months ago|
|internal||5 months ago|
|notifier||6 months ago|
|routing||5 months ago|
|storage||5 months ago|
|streams||5 months ago|
|sync||3 months ago|
|types||6 months ago|
|README.md||2 years ago|
|syncapi.go||6 months ago|
This server is responsible for servicing
/sync requests. It gets its data from the room server output log. Currently, the sync server will:
/syncresponse for the user represented by the provided
sincevalue is provided, and return a valid
next_batchtoken. This contains all rooms the user has been invited to or has joined. For joined rooms, this includes the complete current room state and the most recent 20 (hard-coded) events in the timeline.
sincevalue is provided), as you get invited to, join, or leave rooms they will be reflected correctly in the
statesection of a room is correctly populated with the state of the room at the start of the timeline.
/syncwhich transitions your client to be "joined" will include the complete current room state as per the specification.
timeoutquery parameter value.
When the server gets a
/sync request, it needs to:
The logic for working out which rooms is based on Synapse:
For each room, the /sync response returns the most recent timeline events and the state of the room at the start of the timeline.
The logic for working out which events is not based entirely on Synapse code, as it is known broken with respect to working out
room state. In order to know which events to return, the server needs to calculate room state at various points in the history of
the room. For example, imagine a room with the following 15 events (letters are state events (updated via
'), numbers are timeline events):
index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 (1-based indexing as StreamPosition(0) represents no event) timeline [A, B, C, D, 1, 2, 3, D', 4, D'', 5, B', D''', D'''', 6]
The current state of this room is:
[A, B', C, D''''].
If this room was requested with
?since=14&limit=5 then 1 timeline event would be returned, the most recent one:
15 [ 6 ]
If this room was requested with
?since=9&limit=5 then 5 timeline events would be returned, the most recent ones:
11 12 13 14 15 [5, B', D''', D'''', 6]
The state of the room at the START of the timeline can be represented in 2 ways:
full_statefrom index 0 :
[A, B, C, D''](aka the state between 0-11 exclusive)
[D''](aka the state between 9-11 exclusive)
Servers advance state events (e.g from
D'') based on the state conflict resolution algorithm.
You might think that you could advance the current state by just updating the entry for the
(event type, state_key) tuple
for each state event, but this state can diverge from the state calculated using the state conflict resolution algorithm.
For example, if there are two "simultaneous" updates to the same state key, that is two updates at the same depth in the
event graph, then the final result of the state conflict resolution algorithm might not match the order the events appear
in the timeline.
The correct advancement for state events is represented by the
OutputRoomEvents from the room server.
This version of the sync server uses very simple indexing to calculate room state at various points.
This is inefficient when a very old
since value is provided, or the
full_state is requested, as the state delta becomes
very large. This is mitigated slightly with indexes, but better data structures could be used in the future.
m.room.history_visibilityis not honoured: it is always treated as "shared".
to_devicemessages are not implemented.
prev_batchis not implemented.
limitedflag can lie.
limitfor each room is hard-coded to 20.
full_statequery parameter is not implemented.
set_presencequery parameter is not implemented.
invite_stateis not implemented (for similar reasons to the above point).
sincetoken is provided.