perf(group): reduce websocket fanout serialization

This commit is contained in:
richjohnrambo
2026-10-04 10:15:18 +08:00
parent c46209f4e7
commit b05e8f60dd
10 changed files with 458 additions and 2 deletions
+72
View File
@@ -4334,3 +4334,75 @@ func TestMain(m *testing.M) {
globals.maxSubscriberCount = 1_000_000_000
os.Exit(m.Run())
}
func TestGroupBroadcastReusesSerializedWebSocketPayload(t *testing.T) {
uid1, uid2, uid3 := types.Uid(1), types.Uid(2), types.Uid(3)
sess1 := &Session{sid: "ws-1", proto: WEBSOCK, send: make(chan any, 2)}
sess2 := &Session{sid: "ws-2", proto: WEBSOCK, send: make(chan any, 2)}
sessNoRead := &Session{sid: "ws-no-read", proto: WEBSOCK, send: make(chan any, 2)}
topic := &Topic{
tenantID: 1,
name: "grpShared",
xoriginal: "grpShared",
cat: types.TopicCatGrp,
sessions: map[*Session]perSessionData{
sess1: {uid: uid1},
sess2: {uid: uid2},
sessNoRead: {uid: uid3},
},
perUser: map[types.Uid]perUserData{
uid1: {modeWant: types.ModeCFull, modeGiven: types.ModeCFull},
uid2: {modeWant: types.ModeCFull, modeGiven: types.ModeCFull},
uid3: {modeWant: types.ModeNone, modeGiven: types.ModeNone},
},
}
msg := &ServerComMessage{Data: &MsgServerData{
Topic: "grpShared", From: uid1.UserId(), SeqId: 42, Timestamp: time.Now(), Content: "hello",
}}
topic.broadcastToSessions(msg)
payload1, ok := (<-sess1.send).(sharedServerMessage)
if !ok {
t.Fatal("first WebSocket did not receive a serialized payload")
}
payload2, ok := (<-sess2.send).(sharedServerMessage)
if !ok {
t.Fatal("second WebSocket did not receive a serialized payload")
}
if len(payload1) == 0 || len(payload2) == 0 || &payload1[0] != &payload2[0] {
t.Fatal("group WebSocket recipients did not reuse the same serialized payload")
}
var decoded ServerComMessage
if err := json.Unmarshal(payload1, &decoded); err != nil {
t.Fatalf("invalid shared payload: %v", err)
}
if decoded.Data == nil || decoded.Data.Topic != "grpShared" || decoded.Data.SeqId != 42 || decoded.Data.Content != "hello" {
t.Fatalf("unexpected shared payload: %#v", decoded.Data)
}
if len(sessNoRead.send) != 0 {
t.Fatal("non-reader received a group broadcast")
}
}
func TestSharedBroadcastEligibility(t *testing.T) {
sess := &Session{proto: WEBSOCK}
msg := &ServerComMessage{Data: &MsgServerData{Topic: "grpShared"}}
for _, tc := range []struct {
name string
topic Topic
pssd perSessionData
want bool
}{
{name: "ordinary group", topic: Topic{cat: types.TopicCatGrp}, want: true},
{name: "channel", topic: Topic{cat: types.TopicCatGrp, isChan: true}},
{name: "channel subscription", topic: Topic{cat: types.TopicCatGrp}, pssd: perSessionData{isChanSub: true}},
{name: "p2p", topic: Topic{cat: types.TopicCatP2P}},
} {
t.Run(tc.name, func(t *testing.T) {
if got := tc.topic.canShareSerializedBroadcast(msg, sess, tc.pssd); got != tc.want {
t.Fatalf("eligibility=%v want=%v", got, tc.want)
}
})
}
}