aboutsummaryrefslogtreecommitdiff
path: root/roomserver
diff options
context:
space:
mode:
authorTill <2353100+S7evinK@users.noreply.github.com>2023-07-13 14:19:08 +0200
committerGitHub <noreply@github.com>2023-07-13 14:19:08 +0200
commit5267cc0f54db37b8a71a4caa7148e1dff7ae27c1 (patch)
tree7db7ed3845f1309f1a066a0c7b22aba21f0dd46a /roomserver
parentf12982472c71b8daf3de682c2807989ee695d2cf (diff)
Optimise getting local members and membership counts (#3150)
The previous version was getting **ALL** membership events (as `ClientEvents`, so going through `NewEventFromTrustedJSONWithID`) for a given room. Now we are querying only locally joined users as `ClientEvents`, which should **significantly** reduce allocations. Take for example a large room with 2k membership events, but only 1 local user - avoiding 1999 `NewEventFromTrustedJSONWithID` calls just to calculate the `roomSize` which we can also query by other means. This is also getting called for every `OutputRoomEvent` in the userAPI. Benchmark with 1 local user and 100 remote users. ``` pkg: github.com/matrix-org/dendrite/userapi/consumers cpu: 12th Gen Intel(R) Core(TM) i5-12500H │ old.txt │ new.txt │ │ sec/op │ sec/op vs base │ LocalRoomMembers-16 375.9µ ± 7% 327.6µ ± 6% -12.85% (p=0.000 n=10) │ old.txt │ new.txt │ │ B/op │ B/op vs base │ LocalRoomMembers-16 79.426Ki ± 0% 8.507Ki ± 0% -89.29% (p=0.000 n=10) │ old.txt │ new.txt │ │ allocs/op │ allocs/op vs base │ LocalRoomMembers-16 1015.0 ± 0% 277.0 ± 0% -72.71% (p=0.000 n=10) ```
Diffstat (limited to 'roomserver')
-rw-r--r--roomserver/api/api.go1
-rw-r--r--roomserver/internal/query/query.go14
2 files changed, 15 insertions, 0 deletions
diff --git a/roomserver/api/api.go b/roomserver/api/api.go
index ab56529c..c29406a1 100644
--- a/roomserver/api/api.go
+++ b/roomserver/api/api.go
@@ -227,6 +227,7 @@ type UserRoomserverAPI interface {
QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error
PerformAdminEvacuateUser(ctx context.Context, userID string) (affected []string, err error)
PerformJoin(ctx context.Context, req *PerformJoinRequest) (roomID string, joinedVia spec.ServerName, err error)
+ JoinedUserCount(ctx context.Context, roomID string) (int, error)
}
type FederationRoomserverAPI interface {
diff --git a/roomserver/internal/query/query.go b/roomserver/internal/query/query.go
index 626d3c13..39e3bd0e 100644
--- a/roomserver/internal/query/query.go
+++ b/roomserver/internal/query/query.go
@@ -974,6 +974,20 @@ func (r *Queryer) LocallyJoinedUsers(ctx context.Context, roomVersion gomatrixse
return joinedUsers, nil
}
+func (r *Queryer) JoinedUserCount(ctx context.Context, roomID string) (int, error) {
+ info, err := r.DB.RoomInfo(ctx, roomID)
+ if err != nil {
+ return 0, err
+ }
+ if info == nil {
+ return 0, nil
+ }
+
+ // TODO: this can be further optimised by just using a SELECT COUNT query
+ nids, err := r.DB.GetMembershipEventNIDsForRoom(ctx, info.RoomNID, true, false)
+ return len(nids), err
+}
+
// nolint:gocyclo
func (r *Queryer) QueryRestrictedJoinAllowed(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (string, error) {
// Look up if we know anything about the room. If it doesn't exist