diff --git a/src/github.com/matrix-org/dendrite/syncserver/sync/requestpool.go b/src/github.com/matrix-org/dendrite/syncserver/sync/requestpool.go index 15c588455..b3c38aca3 100644 --- a/src/github.com/matrix-org/dendrite/syncserver/sync/requestpool.go +++ b/src/github.com/matrix-org/dendrite/syncserver/sync/requestpool.go @@ -139,7 +139,8 @@ func (rp *RequestPool) currentSyncForUser(req syncRequest) (*types.Response, err // TODO: handle ignored users - // TODO: Implement https://github.com/matrix-org/synapse/blob/v0.19.3/synapse/handlers/sync.py#L821 + // TODO: Work out *which* rooms to return to the client + // Based on https://github.com/matrix-org/synapse/blob/v0.19.3/synapse/handlers/sync.py#L821 // 1) Get the CURRENT joined room list for this user // 2) Get membership list changes for this user between the provided stream position and now. // 3) For each room which has membership list changes: @@ -149,6 +150,37 @@ func (rp *RequestPool) currentSyncForUser(req syncRequest) (*types.Response, err // c) Check if the user is CURRENTLY left/banned. If so, add room to 'archived' block. // Synapse has a TODO: How do we handle ban -> leave in same batch? // 4) Add joined rooms (joined room list) + // Problem statement: + // TODO: For each room being returned, work out *which* events to return to the client. + // This involves calculating the 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=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: + // - The 'full_state' from index 0 : [A, B, C, D''] (aka the state between 0-11 exclusive) + // - A partial state from index 9 : [D''] (aka the state between 9-11 exclusive) + // + // The /sync response returns the most recent timeline events and the state of the room at the start of the timeline, for each room. + // + // Aside: There are 2 ways that a server can advance state events e.g from D' to D'': + // 1) by a tuple of (event type, state key) + // 2) by the state conflict resolution algorithm + // Dendrite MUST do this by 2), and that is represented by the add_state_ids and remove_state_ids that + // are in OutputRoomEvents from the room server. + + // This version of dendrite 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. + evs, err := rp.db.EventsInRange(req.since, currentPos) if err != nil { return nil, err