aboutsummaryrefslogtreecommitdiff
path: root/syncapi/streams/stream_pdu.go
diff options
context:
space:
mode:
authorTill <2353100+S7evinK@users.noreply.github.com>2023-01-17 10:08:23 +0100
committerGitHub <noreply@github.com>2023-01-17 10:08:23 +0100
commit0d0280cf5ff71ec975b17d0f6dadcae7e46574b5 (patch)
treea13e07f0f775029c1929792b072841657b3a5bcf /syncapi/streams/stream_pdu.go
parent8582c7520abbfca680da9ba16e40a9a92b9fd21c (diff)
`/sync` performance optimizations (#2927)
Since #2849 there is no limit for the current state we fetch to calculate history visibility. In large rooms this can cause us to fetch thousands of membership events we don't really care about. This now only gets the state event types and senders in our timeline, which should significantly reduce the amount of events we fetch from the database. Also removes `MaxTopologicalPosition`, as it is an unnecessary DB call, given we use the result in `topological_position < $1` calls.
Diffstat (limited to 'syncapi/streams/stream_pdu.go')
-rw-r--r--syncapi/streams/stream_pdu.go35
1 files changed, 24 insertions, 11 deletions
diff --git a/syncapi/streams/stream_pdu.go b/syncapi/streams/stream_pdu.go
index 4664276c..44013e37 100644
--- a/syncapi/streams/stream_pdu.go
+++ b/syncapi/streams/stream_pdu.go
@@ -384,19 +384,32 @@ func applyHistoryVisibilityFilter(
roomID, userID string,
recentEvents []*gomatrixserverlib.HeaderedEvent,
) ([]*gomatrixserverlib.HeaderedEvent, error) {
- // We need to make sure we always include the latest states events, if they are in the timeline.
- // We grep at least limit * 2 events, to ensure we really get the needed events.
- filter := gomatrixserverlib.DefaultStateFilter()
- stateEvents, err := snapshot.CurrentState(ctx, roomID, &filter, nil)
- if err != nil {
- // Not a fatal error, we can continue without the stateEvents,
- // they are only needed if there are state events in the timeline.
- logrus.WithError(err).Warnf("Failed to get current room state for history visibility")
+ // We need to make sure we always include the latest state events, if they are in the timeline.
+ alwaysIncludeIDs := make(map[string]struct{})
+ var stateTypes []string
+ var senders []string
+ for _, ev := range recentEvents {
+ if ev.StateKey() != nil {
+ stateTypes = append(stateTypes, ev.Type())
+ senders = append(senders, ev.Sender())
+ }
}
- alwaysIncludeIDs := make(map[string]struct{}, len(stateEvents))
- for _, ev := range stateEvents {
- alwaysIncludeIDs[ev.EventID()] = struct{}{}
+
+ // Only get the state again if there are state events in the timeline
+ if len(stateTypes) > 0 {
+ filter := gomatrixserverlib.DefaultStateFilter()
+ filter.Types = &stateTypes
+ filter.Senders = &senders
+ stateEvents, err := snapshot.CurrentState(ctx, roomID, &filter, nil)
+ if err != nil {
+ return nil, fmt.Errorf("failed to get current room state for history visibility calculation: %w", err)
+ }
+
+ for _, ev := range stateEvents {
+ alwaysIncludeIDs[ev.EventID()] = struct{}{}
+ }
}
+
startTime := time.Now()
events, err := internal.ApplyHistoryVisibilityFilter(ctx, snapshot, rsAPI, recentEvents, alwaysIncludeIDs, userID, "sync")
if err != nil {