mirror of
https://github.com/livekit/livekit.git
synced 2026-08-06 23:39:43 +00:00
Ensure older participant session update does not go out after a newer (#1372)
* Ensure older participant session update does not go out after a newer session has joined. * fix tests * change comment * do not send older version
This commit is contained in:
+22
-10
@@ -900,6 +900,10 @@ func (r *Room) broadcastParticipantState(p types.LocalParticipant, opts broadcas
|
||||
}
|
||||
|
||||
func (r *Room) sendParticipantUpdates(updates []*livekit.ParticipantInfo) {
|
||||
if len(updates) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for _, op := range r.GetParticipants() {
|
||||
err := op.SendParticipantUpdate(updates)
|
||||
if err != nil {
|
||||
@@ -960,16 +964,24 @@ func (r *Room) pushAndDequeueUpdates(pi *livekit.ParticipantInfo, isImmediate bo
|
||||
shouldSend := isImmediate || pi.IsPublisher
|
||||
|
||||
if existing != nil {
|
||||
if pi.Sid != existing.Sid {
|
||||
// session change, need to send immediately
|
||||
isImmediate = true
|
||||
existing.State = livekit.ParticipantInfo_DISCONNECTED
|
||||
updates = append(updates, existing)
|
||||
} else if pi.Version < existing.Version {
|
||||
// out of order update
|
||||
return nil
|
||||
} else if shouldSend {
|
||||
updates = append(updates, existing)
|
||||
if pi.Sid == existing.Sid {
|
||||
// same participant session
|
||||
if pi.Version < existing.Version {
|
||||
// out of order update
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
// different participant sessions
|
||||
if existing.JoinedAt < pi.JoinedAt {
|
||||
// existing is older, synthesize a DISCONNECT for older and
|
||||
// send immediately along with newer session to signal switch
|
||||
shouldSend = true
|
||||
existing.State = livekit.ParticipantInfo_DISCONNECTED
|
||||
updates = append(updates, existing)
|
||||
} else {
|
||||
// older session update, newer session has already become active, so nothing to do
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-1
@@ -211,28 +211,33 @@ func TestPushAndDequeueUpdates(t *testing.T) {
|
||||
Sid: "1",
|
||||
IsPublisher: true,
|
||||
Version: 1,
|
||||
JoinedAt: 0,
|
||||
}
|
||||
publisher1v2 := &livekit.ParticipantInfo{
|
||||
Identity: identity,
|
||||
Sid: "1",
|
||||
IsPublisher: true,
|
||||
Version: 2,
|
||||
JoinedAt: 1,
|
||||
}
|
||||
publisher2 := &livekit.ParticipantInfo{
|
||||
Identity: identity,
|
||||
Sid: "2",
|
||||
IsPublisher: true,
|
||||
Version: 1,
|
||||
JoinedAt: 2,
|
||||
}
|
||||
subscriber1v1 := &livekit.ParticipantInfo{
|
||||
Identity: identity,
|
||||
Sid: "1",
|
||||
Version: 1,
|
||||
JoinedAt: 0,
|
||||
}
|
||||
subscriber1v2 := &livekit.ParticipantInfo{
|
||||
Identity: identity,
|
||||
Sid: "1",
|
||||
Version: 2,
|
||||
JoinedAt: 1,
|
||||
}
|
||||
|
||||
requirePIEquals := func(t *testing.T, a, b *livekit.ParticipantInfo) {
|
||||
@@ -267,6 +272,17 @@ func TestPushAndDequeueUpdates(t *testing.T) {
|
||||
requirePIEquals(t, subscriber1v2, queued)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "both versions updates when immediate",
|
||||
pi: subscriber1v2,
|
||||
existing: subscriber1v1,
|
||||
immediate: true,
|
||||
expected: []*livekit.ParticipantInfo{subscriber1v2},
|
||||
validate: func(t *testing.T, rm *Room, _ []*livekit.ParticipantInfo) {
|
||||
queued := rm.batchedUpdates[livekit.ParticipantIdentity(identity)]
|
||||
require.Nil(t, queued)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "out of order updates are rejected",
|
||||
pi: subscriber1v1,
|
||||
@@ -294,7 +310,7 @@ func TestPushAndDequeueUpdates(t *testing.T) {
|
||||
name: "when switching to publisher, queue is cleared",
|
||||
pi: publisher1v2,
|
||||
existing: subscriber1v1,
|
||||
expected: []*livekit.ParticipantInfo{subscriber1v1, publisher1v2},
|
||||
expected: []*livekit.ParticipantInfo{publisher1v2},
|
||||
validate: func(t *testing.T, rm *Room, updates []*livekit.ParticipantInfo) {
|
||||
require.Empty(t, rm.batchedUpdates)
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user