mirror of
https://github.com/matrix-org/sliding-sync.git
synced 2025-03-10 13:37:11 +00:00
102 lines
3.5 KiB
Go
102 lines
3.5 KiB
Go
package syncv3
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/matrix-org/sliding-sync/sync2"
|
|
"github.com/matrix-org/sliding-sync/sync3"
|
|
"github.com/matrix-org/sliding-sync/testutils"
|
|
"github.com/rs/zerolog"
|
|
)
|
|
|
|
// The purpose of this benchmark is to ensure that sync v3 responds quickly regardless of how many
|
|
// rooms the user has on their account. The first initial sync to fetch the rooms are ignored for
|
|
// the purposes of the benchmark, only subsequent requests are taken into account. We expect this
|
|
// value to grow slowly (searching more rows in a database, looping more elements in an array) but
|
|
// this should not grow so quickly that it impacts performance or else something has gone terribly
|
|
// wrong.
|
|
func BenchmarkNumRooms(b *testing.B) {
|
|
testutils.Quiet = true
|
|
for _, numRooms := range []int{100, 200, 400, 800} {
|
|
n := numRooms
|
|
b.Run(fmt.Sprintf("num_rooms_%d", n), func(b *testing.B) {
|
|
benchNumV2Rooms(n, b)
|
|
})
|
|
}
|
|
}
|
|
|
|
func benchNumV2Rooms(numRooms int, b *testing.B) {
|
|
// setup code
|
|
boolFalse := false
|
|
pqString := testutils.PrepareDBConnectionString()
|
|
v2 := runTestV2Server(b)
|
|
v3 := runTestServer(b, v2, pqString)
|
|
zerolog.SetGlobalLevel(zerolog.Disabled)
|
|
defer v2.close()
|
|
defer v3.close()
|
|
allRooms := make([]roomEvents, numRooms)
|
|
for i := 0; i < len(allRooms); i++ {
|
|
ts := time.Now().Add(time.Duration(i) * time.Minute)
|
|
roomName := fmt.Sprintf("My Room %d", i)
|
|
allRooms[i] = roomEvents{
|
|
roomID: fmt.Sprintf("!benchNumV2Rooms_%d:localhost", i),
|
|
name: roomName,
|
|
events: append(createRoomState(b, alice, ts), []json.RawMessage{
|
|
testutils.NewStateEvent(b, "m.room.name", "", alice, map[string]interface{}{"name": roomName}, testutils.WithTimestamp(ts.Add(3*time.Second))),
|
|
testutils.NewEvent(b, "m.room.message", alice, map[string]interface{}{"body": "A"}, testutils.WithTimestamp(ts.Add(4*time.Second))),
|
|
testutils.NewEvent(b, "m.room.message", alice, map[string]interface{}{"body": "B"}, testutils.WithTimestamp(ts.Add(5*time.Second))),
|
|
testutils.NewEvent(b, "m.room.message", alice, map[string]interface{}{"body": "C"}, testutils.WithTimestamp(ts.Add(6*time.Second))),
|
|
}...),
|
|
}
|
|
}
|
|
v2.addAccount(b, alice, aliceToken)
|
|
v2.queueResponse(alice, sync2.SyncResponse{
|
|
Rooms: sync2.SyncRoomsResponse{
|
|
Join: v2JoinTimeline(allRooms...),
|
|
},
|
|
})
|
|
// do the initial request
|
|
v3.mustDoV3Request(b, aliceToken, sync3.Request{
|
|
Lists: map[string]sync3.RequestList{
|
|
"a": {
|
|
Ranges: sync3.SliceRanges{
|
|
[2]int64{0, 20}, // first few rooms
|
|
},
|
|
RoomSubscription: sync3.RoomSubscription{
|
|
TimelineLimit: 3,
|
|
},
|
|
}},
|
|
})
|
|
|
|
b.ResetTimer() // don't count setup code
|
|
|
|
// these should all take roughly the same amount of time, regardless of the value of `numRooms`
|
|
for n := 0; n < b.N; n++ {
|
|
v3.mustDoV3Request(b, aliceToken, sync3.Request{
|
|
Lists: map[string]sync3.RequestList{
|
|
"a": {
|
|
// always use a fixed range else we will scale O(n) with the number of rooms
|
|
Ranges: sync3.SliceRanges{
|
|
[2]int64{0, 20}, // first few rooms
|
|
},
|
|
// include a filter to ensure we loop over rooms
|
|
Filters: &sync3.RequestFilters{
|
|
IsEncrypted: &boolFalse,
|
|
},
|
|
// include a few required state events to force us to query the database
|
|
// include a few timeline events to force us to query the database
|
|
RoomSubscription: sync3.RoomSubscription{
|
|
TimelineLimit: 3,
|
|
RequiredState: [][2]string{
|
|
{"m.room.create", ""},
|
|
{"m.room.member", alice},
|
|
},
|
|
},
|
|
}},
|
|
})
|
|
}
|
|
}
|