Fix ordering when backfilling (#1000)

* Fix ordering when backfilling

The problem was that we weren't sorting the returned events
by depth when sending them back to the caller, instead we
were sorting by prev_events which is not the same thing.

* Fixup tests
This commit is contained in:
Kegsay 2020-05-01 16:41:13 +01:00 committed by GitHub
parent f7cfa75886
commit 36bbb25561
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 110 additions and 10 deletions

View file

@ -210,15 +210,16 @@ func (r *messagesReq) retrieveEvents() (
}
// Sort the events to ensure we send them in the right order.
events = gomatrixserverlib.HeaderedReverseTopologicalOrdering(
events,
gomatrixserverlib.TopologicalOrderByPrevEvents,
)
if r.backwardOrdering {
// This reverses the array from old->new to new->old
sort.SliceStable(events, func(i, j int) bool {
return true
})
reversed := func(in []gomatrixserverlib.HeaderedEvent) []gomatrixserverlib.HeaderedEvent {
out := make([]gomatrixserverlib.HeaderedEvent, len(in))
for i := 0; i < len(in); i++ {
out[i] = in[len(in)-i-1]
}
return out
}
events = reversed(events)
}
// Convert all of the events into client events.
@ -259,6 +260,7 @@ func (r *messagesReq) retrieveEvents() (
// to them by the event on their left, therefore we need to decrement the
// end position we send in the response if we're going backward.
end.PDUPosition--
end.EDUTypingPosition += 1000
}
// The lowest token value is 1, therefore we need to manually set it to that
@ -345,10 +347,23 @@ func (r *messagesReq) handleNonEmptyEventsSlice(streamEvents []types.StreamEvent
// Append the events ve previously retrieved locally.
events = append(events, r.db.StreamEventsToEvents(nil, streamEvents)...)
sort.Sort(eventsByDepth(events))
return
}
type eventsByDepth []gomatrixserverlib.HeaderedEvent
func (e eventsByDepth) Len() int {
return len(e)
}
func (e eventsByDepth) Swap(i, j int) {
e[i], e[j] = e[j], e[i]
}
func (e eventsByDepth) Less(i, j int) bool {
return e[i].Depth() < e[j].Depth()
}
// backfill performs a backfill request over the federation on another
// homeserver in the room.
// See: https://matrix.org/docs/spec/server_server/latest#get-matrix-federation-v1-backfill-roomid
@ -375,17 +390,24 @@ func (r *messagesReq) backfill(roomID string, fromEventIDs []string, limit int)
// Currently, this can race with live events for the room and cause problems. It's also just a bit unclear
// when you have multiple entry points to write events.
// we have to order these by depth, starting with the lowest because otherwise the topology tokens
// will skip over events that have the same depth but different stream positions due to the query which is:
// - anything less than the depth OR
// - anything with the same depth and a lower stream position.
sort.Sort(eventsByDepth(res.Events))
// Store the events in the database, while marking them as unfit to show
// up in responses to sync requests.
for i := range res.Events {
if _, err = r.db.WriteEvent(
_, err = r.db.WriteEvent(
r.ctx,
&res.Events[i],
[]gomatrixserverlib.HeaderedEvent{},
[]string{},
[]string{},
nil, true,
); err != nil {
)
if err != nil {
return nil, err
}
}