rework multi-node routing, cleaner design for reconnection

This commit is contained in:
David Zhao
2021-01-30 22:24:08 -08:00
parent 28e73bd109
commit 2cf2c448be
23 changed files with 702 additions and 661 deletions
+2 -5
View File
@@ -23,7 +23,7 @@ type MessageSource interface {
ReadChan() <-chan proto.Message
}
type ParticipantCallback func(roomId, participantId, participantName string, requestSource MessageSource, responseSink MessageSink)
type ParticipantCallback func(roomName, identity string, requestSource MessageSource, responseSink MessageSink)
// Router allows multiple nodes to coordinate the participant session
//counterfeiter:generate . Router
@@ -36,11 +36,8 @@ type Router interface {
GetNode(nodeId string) (*livekit.Node, error)
ListNodes() ([]*livekit.Node, error)
// functions for websocket handler
GetRequestSink(participantId string) (MessageSink, error)
GetResponseSource(participantId string) (MessageSource, error)
// participant signal connection is ready to start
StartParticipantSignal(roomName, participantId, participantName string) error
StartParticipantSignal(roomName, identity string) (reqSink MessageSink, resSource MessageSource, err error)
// when a new participant's RTC connection is ready to start
OnNewParticipantRTC(callback ParticipantCallback)
+16 -20
View File
@@ -59,30 +59,26 @@ func (r *LocalRouter) ListNodes() ([]*livekit.Node, error) {
}, nil
}
func (r *LocalRouter) StartParticipantSignal(roomName, participantId, participantName string) error {
func (r *LocalRouter) StartParticipantSignal(roomName, identity string) (reqSink MessageSink, resSource MessageSource, err error) {
// treat it as a new participant connecting
if r.onNewParticipant == nil {
return ErrHandlerNotDefined
return nil, nil, ErrHandlerNotDefined
}
// index channels by roomName | identity
key := participantKey(roomName, identity)
reqChan := r.getOrCreateMessageChannel(r.requestChannels, key)
resChan := r.getOrCreateMessageChannel(r.responseChannels, key)
r.onNewParticipant(
roomName,
participantId,
participantName,
identity,
// request source
r.getOrCreateMessageChannel(r.requestChannels, participantId),
reqChan,
// response sink
r.getOrCreateMessageChannel(r.responseChannels, participantId),
resChan,
)
return nil
}
// for a local router, sink and source are pointing to the same spot
func (r *LocalRouter) GetRequestSink(participantId string) (MessageSink, error) {
return r.getOrCreateMessageChannel(r.requestChannels, participantId), nil
}
func (r *LocalRouter) GetResponseSource(participantId string) (MessageSource, error) {
return r.getOrCreateMessageChannel(r.responseChannels, participantId), nil
return reqChan, resChan, nil
}
func (r *LocalRouter) OnNewParticipantRTC(callback ParticipantCallback) {
@@ -106,10 +102,10 @@ func (r *LocalRouter) statsWorker() {
}
}
func (r *LocalRouter) getOrCreateMessageChannel(target map[string]*MessageChannel, participantId string) *MessageChannel {
func (r *LocalRouter) getOrCreateMessageChannel(target map[string]*MessageChannel, key string) *MessageChannel {
r.lock.Lock()
defer r.lock.Unlock()
mc := target[participantId]
mc := target[key]
if mc != nil {
return mc
@@ -118,10 +114,10 @@ func (r *LocalRouter) getOrCreateMessageChannel(target map[string]*MessageChanne
mc = NewMessageChannel()
mc.OnClose(func() {
r.lock.Lock()
delete(target, participantId)
delete(target, key)
r.lock.Unlock()
})
target[participantId] = mc
target[key] = mc
return mc
}
+3 -3
View File
@@ -24,12 +24,12 @@ func TestMessageChannel_WriteMessageClosed(t *testing.T) {
go func() {
defer wg.Done()
for i := 0; i < 100; i++ {
m.WriteMessage(&livekit.RouterMessage{})
m.WriteMessage(&livekit.RTCNodeMessage{})
}
}()
m.WriteMessage(&livekit.RouterMessage{})
m.WriteMessage(&livekit.RTCNodeMessage{})
m.Close()
m.WriteMessage(&livekit.RouterMessage{})
m.WriteMessage(&livekit.RTCNodeMessage{})
wg.Wait()
}
+85 -30
View File
@@ -21,38 +21,57 @@ const (
var redisCtx = context.Background()
// location of the participant's RTC connection, hash
func participantRTCKey(participantId string) string {
return "participant_rtc:" + participantId
func participantRTCKey(participantKey string) string {
return "participant_rtc:" + participantKey
}
// location of the participant's Signal connection, hash
func participantSignalKey(participantId string) string {
return "participant_signal:" + participantId
func participantSignalKey(connectionId string) string {
return "participant_signal:" + connectionId
}
func nodeChannel(nodeId string) string {
return "node_channel:" + nodeId
func rtcNodeChannel(nodeId string) string {
return "rtc_channel:" + nodeId
}
func publishRouterMessage(rc *redis.Client, nodeId string, participantId string, msg proto.Message) error {
rm := &livekit.RouterMessage{
ParticipantId: participantId,
func signalNodeChannel(nodeId string) string {
return "signal_channel:" + nodeId
}
func publishRTCMessage(rc *redis.Client, nodeId string, participantKey string, msg proto.Message) error {
rm := &livekit.RTCNodeMessage{
ParticipantKey: participantKey,
}
switch o := msg.(type) {
case *livekit.StartSession:
rm.Message = &livekit.RouterMessage_StartSession{
rm.Message = &livekit.RTCNodeMessage_StartSession{
StartSession: o,
}
case *livekit.SignalRequest:
rm.Message = &livekit.RouterMessage_Request{
rm.Message = &livekit.RTCNodeMessage_Request{
Request: o,
}
default:
return errInvalidRouterMessage
}
data, err := proto.Marshal(rm)
if err != nil {
return err
}
return rc.Publish(redisCtx, rtcNodeChannel(nodeId), data).Err()
}
func publishSignalMessage(rc *redis.Client, nodeId string, connectionId string, msg proto.Message) error {
rm := &livekit.SignalNodeMessage{
ConnectionId: connectionId,
}
switch o := msg.(type) {
case *livekit.SignalResponse:
rm.Message = &livekit.RouterMessage_Response{
rm.Message = &livekit.SignalNodeMessage_Response{
Response: o,
}
case *livekit.EndSession:
rm.Message = &livekit.RouterMessage_EndSession{
rm.Message = &livekit.SignalNodeMessage_EndSession{
EndSession: o,
}
default:
@@ -62,42 +81,78 @@ func publishRouterMessage(rc *redis.Client, nodeId string, participantId string,
if err != nil {
return err
}
return rc.Publish(redisCtx, nodeChannel(nodeId), data).Err()
return rc.Publish(redisCtx, signalNodeChannel(nodeId), data).Err()
}
type RedisSink struct {
rc *redis.Client
nodeId string
participantId string
isClosed utils.AtomicFlag
onClose func()
type RTCNodeSink struct {
rc *redis.Client
nodeId string
participantKey string
isClosed utils.AtomicFlag
onClose func()
}
func NewRedisSink(rc *redis.Client, nodeId, participantId string) *RedisSink {
return &RedisSink{
rc: rc,
nodeId: nodeId,
participantId: participantId,
func NewRTCNodeSink(rc *redis.Client, nodeId, participantKey string) *RTCNodeSink {
return &RTCNodeSink{
rc: rc,
nodeId: nodeId,
participantKey: participantKey,
}
}
func (s *RedisSink) WriteMessage(msg proto.Message) error {
func (s *RTCNodeSink) WriteMessage(msg proto.Message) error {
if s.isClosed.Get() {
return ErrChannelClosed
}
return publishRouterMessage(s.rc, s.nodeId, s.participantId, msg)
return publishRTCMessage(s.rc, s.nodeId, s.participantKey, msg)
}
func (s *RedisSink) Close() {
func (s *RTCNodeSink) Close() {
if !s.isClosed.TrySet(true) {
return
}
publishRouterMessage(s.rc, s.nodeId, s.participantId, &livekit.EndSession{})
if s.onClose != nil {
s.onClose()
}
}
func (s *RedisSink) OnClose(f func()) {
func (s *RTCNodeSink) OnClose(f func()) {
s.onClose = f
}
type SignalNodeSink struct {
rc *redis.Client
nodeId string
connectionId string
isClosed utils.AtomicFlag
onClose func()
}
func NewSignalNodeSink(rc *redis.Client, nodeId, connectionId string) *SignalNodeSink {
return &SignalNodeSink{
rc: rc,
nodeId: nodeId,
connectionId: connectionId,
}
}
func (s *SignalNodeSink) WriteMessage(msg proto.Message) error {
if s.isClosed.Get() {
return ErrChannelClosed
}
return publishSignalMessage(s.rc, s.nodeId, s.connectionId, msg)
}
func (s *SignalNodeSink) Close() {
if !s.isClosed.TrySet(true) {
return
}
publishSignalMessage(s.rc, s.nodeId, s.connectionId, &livekit.EndSession{})
if s.onClose != nil {
s.onClose()
}
}
func (s *SignalNodeSink) OnClose(f func()) {
s.onClose = f
}
+141 -90
View File
@@ -30,8 +30,11 @@ type RedisRouter struct {
ctx context.Context
once sync.Once
redisSinks map[string]*RedisSink
cancel func()
// map of participantKey => RTCNodeSink
rtcSinks map[string]*RTCNodeSink
// map of connectionId => SignalNodeSink
signalSinks map[string]*SignalNodeSink
cancel func()
}
func NewRedisRouter(currentNode LocalNode, rc *redis.Client) *RedisRouter {
@@ -39,7 +42,8 @@ func NewRedisRouter(currentNode LocalNode, rc *redis.Client) *RedisRouter {
LocalRouter: *NewLocalRouter(currentNode),
rc: rc,
once: sync.Once{},
redisSinks: make(map[string]*RedisSink),
rtcSinks: make(map[string]*RTCNodeSink),
signalSinks: make(map[string]*SignalNodeSink),
}
rr.ctx, rr.cancel = context.WithCancel(context.Background())
rr.cr = utils.NewCachedRedis(rr.ctx, rr.rc)
@@ -110,55 +114,44 @@ func (r *RedisRouter) ListNodes() ([]*livekit.Node, error) {
return nodes, nil
}
// for a local router, sink and source are pointing to the same spot
func (r *RedisRouter) GetRequestSink(participantId string) (MessageSink, error) {
// request should go to RTC node
rtcNode, err := r.getParticipantRTCNode(participantId)
if err != nil {
return nil, err
}
sink := r.getOrCreateRedisSink(rtcNode, participantId)
return sink, nil
}
func (r *RedisRouter) GetResponseSource(participantId string) (MessageSource, error) {
// a message channel that we'll send data into
source := r.getOrCreateMessageChannel(r.responseChannels, participantId)
return source, nil
}
// signal connection sets up paths to the RTC node, and starts to route messages to that message queue
func (r *RedisRouter) StartParticipantSignal(roomName, participantId, participantName string) error {
func (r *RedisRouter) StartParticipantSignal(roomName, identity string) (reqSink MessageSink, resSource MessageSource, err error) {
// find the node where the room is hosted at
rtcNode, err := r.GetNodeForRoom(roomName)
if err != nil {
return err
return
}
// create a new connection id
connectionId := utils.NewGuid("CO_")
pKey := participantKey(roomName, identity)
// map signal & rtc nodes
if err = r.setParticipantSignalNode(participantId, r.currentNode.Id); err != nil {
return err
}
if err := r.setParticipantRTCNode(participantId, rtcNode); err != nil {
return err
if err = r.setParticipantSignalNode(connectionId, r.currentNode.Id); err != nil {
return
}
sink, err := r.GetRequestSink(participantId)
if err != nil {
return err
}
sink := r.getOrCreateRTCSink(rtcNode, pKey)
// sends a message to start session
return sink.WriteMessage(&livekit.StartSession{
RoomName: roomName,
ParticipantName: participantName,
err = sink.WriteMessage(&livekit.StartSession{
RoomName: roomName,
Identity: identity,
// connection id is to allow the RTC node to identify where to route the message back to
ConnectionId: connectionId,
})
if err != nil {
return
}
// index by connectionId, since there may be multiple connections for the participant
resChan := r.getOrCreateMessageChannel(r.responseChannels, connectionId)
return sink, resChan, nil
}
func (r *RedisRouter) startParticipantRTC(roomName, participantId, participantName string) error {
func (r *RedisRouter) startParticipantRTC(ss *livekit.StartSession, participantKey string) error {
// find the node where the room is hosted at
rtcNode, err := r.GetNodeForRoom(roomName)
rtcNode, err := r.GetNodeForRoom(ss.RoomName)
if err != nil {
return err
}
@@ -169,8 +162,12 @@ func (r *RedisRouter) startParticipantRTC(roomName, participantId, participantNa
return ErrIncorrectRTCNode
}
if err := r.setParticipantRTCNode(participantKey, rtcNode); err != nil {
return err
}
// find signal node to send responses back
signalNode, err := r.getParticipantSignalNode(participantId)
signalNode, err := r.getParticipantSignalNode(ss.ConnectionId)
if err != nil {
return err
}
@@ -180,12 +177,12 @@ func (r *RedisRouter) startParticipantRTC(roomName, participantId, participantNa
return ErrHandlerNotDefined
}
resSink := r.getOrCreateRedisSink(signalNode, participantId)
reqChan := r.getOrCreateMessageChannel(r.requestChannels, participantKey)
resSink := r.getOrCreateSignalSink(signalNode, ss.ConnectionId)
r.onNewParticipant(
roomName,
participantId,
participantName,
r.getOrCreateMessageChannel(r.requestChannels, participantId),
ss.RoomName,
ss.Identity,
reqChan,
resSink,
)
return nil
@@ -194,7 +191,8 @@ func (r *RedisRouter) startParticipantRTC(roomName, participantId, participantNa
func (r *RedisRouter) Start() error {
r.once.Do(func() {
go r.statsWorker()
go r.subscribeWorker()
go r.rtcWorker()
go r.signalWorker()
})
return nil
}
@@ -203,48 +201,67 @@ func (r *RedisRouter) Stop() {
r.cancel()
}
func (r *RedisRouter) setParticipantRTCNode(participantId, nodeId string) error {
r.cr.Expire(participantRTCKey(participantId))
err := r.rc.Set(r.ctx, participantRTCKey(participantId), nodeId, participantMappingTTL).Err()
func (r *RedisRouter) setParticipantRTCNode(participantKey, nodeId string) error {
r.cr.Expire(participantRTCKey(participantKey))
err := r.rc.Set(r.ctx, participantRTCKey(participantKey), nodeId, participantMappingTTL).Err()
if err != nil {
err = errors.Wrap(err, "could not set rtc node")
}
return err
}
func (r *RedisRouter) setParticipantSignalNode(participantId, nodeId string) error {
r.cr.Expire(participantSignalKey(participantId))
if err := r.rc.Set(r.ctx, participantSignalKey(participantId), nodeId, participantMappingTTL).Err(); err != nil {
func (r *RedisRouter) setParticipantSignalNode(connectionId, nodeId string) error {
r.cr.Expire(participantSignalKey(connectionId))
if err := r.rc.Set(r.ctx, participantSignalKey(connectionId), nodeId, participantMappingTTL).Err(); err != nil {
return errors.Wrap(err, "could not set signal node")
}
return nil
}
func (r *RedisRouter) getOrCreateRedisSink(nodeId string, participantId string) *RedisSink {
func (r *RedisRouter) getOrCreateRTCSink(nodeId string, participantKey string) *RTCNodeSink {
r.lock.Lock()
defer r.lock.Unlock()
sink := r.redisSinks[participantId]
sink := r.rtcSinks[participantKey]
if sink != nil {
return sink
}
sink = NewRedisSink(r.rc, nodeId, participantId)
sink = NewRTCNodeSink(r.rc, nodeId, participantKey)
sink.OnClose(func() {
r.lock.Lock()
delete(r.redisSinks, participantId)
delete(r.rtcSinks, participantKey)
r.lock.Unlock()
})
r.redisSinks[participantId] = sink
r.rtcSinks[participantKey] = sink
return sink
}
func (r *RedisRouter) getParticipantRTCNode(participantId string) (string, error) {
return r.cr.CachedGet(participantRTCKey(participantId))
func (r *RedisRouter) getOrCreateSignalSink(nodeId string, connectionId string) *SignalNodeSink {
r.lock.Lock()
defer r.lock.Unlock()
sink := r.signalSinks[connectionId]
if sink != nil {
return sink
}
sink = NewSignalNodeSink(r.rc, nodeId, connectionId)
sink.OnClose(func() {
r.lock.Lock()
delete(r.signalSinks, connectionId)
r.lock.Unlock()
})
r.signalSinks[connectionId] = sink
return sink
}
func (r *RedisRouter) getParticipantSignalNode(participantId string) (nodeId string, err error) {
return r.cr.CachedGet(participantSignalKey(participantId))
func (r *RedisRouter) getParticipantRTCNode(participantKey string) (string, error) {
return r.cr.CachedGet(participantRTCKey(participantKey))
}
func (r *RedisRouter) getParticipantSignalNode(connectionId string) (nodeId string, err error) {
return r.cr.CachedGet(participantSignalKey(connectionId))
}
// update node stats and cleanup
@@ -259,13 +276,13 @@ func (r *RedisRouter) statsWorker() {
}
}
func (r *RedisRouter) subscribeWorker() {
sub := r.rc.Subscribe(redisCtx, nodeChannel(r.currentNode.Id))
// worker that consumes signal channel and processes
func (r *RedisRouter) signalWorker() {
sub := r.rc.Subscribe(redisCtx, signalNodeChannel(r.currentNode.Id))
defer func() {
logger.Debugw("finishing redis subscribeWorker", "node", r.currentNode.Id)
logger.Debugw("finishing redis signalWorker", "node", r.currentNode.Id)
}()
logger.Debugw("starting redis subscribeWorker", "node", r.currentNode.Id)
logger.Debugw("starting redis signalWorker", "node", r.currentNode.Id)
for r.ctx.Err() == nil {
obj, err := sub.Receive(r.ctx)
if err != nil {
@@ -283,42 +300,24 @@ func (r *RedisRouter) subscribeWorker() {
continue
}
rm := livekit.RouterMessage{}
rm := livekit.SignalNodeMessage{}
err = proto.Unmarshal([]byte(msg.Payload), &rm)
pId := rm.ParticipantId
connectionId := rm.ConnectionId
switch rmb := rm.Message.(type) {
case *livekit.RouterMessage_StartSession:
logger.Infow("received router startSession", "node", r.currentNode.Id,
"participant", pId)
// RTC session should start on this node
err = r.startParticipantRTC(rmb.StartSession.RoomName, pId, rmb.StartSession.ParticipantName)
if err != nil {
logger.Errorw("could not start participant", "error", err)
}
case *livekit.RouterMessage_Request:
// in the event the current node is an RTC node, push to request channels
reqSink := r.getOrCreateMessageChannel(r.requestChannels, pId)
err = reqSink.WriteMessage(rmb.Request)
if err != nil {
logger.Errorw("could not write to request channel",
"participant", pId,
"error", err)
}
case *livekit.RouterMessage_Response:
case *livekit.SignalNodeMessage_Response:
// in the event the current node is an Signal node, push to response channels
resSink := r.getOrCreateMessageChannel(r.responseChannels, pId)
resSink := r.getOrCreateMessageChannel(r.responseChannels, connectionId)
err = resSink.WriteMessage(rmb.Response)
if err != nil {
logger.Errorw("could not write to response channel",
"participant", pId,
"connectionId", connectionId,
"error", err)
}
case *livekit.RouterMessage_EndSession:
signalNode, err := r.getParticipantRTCNode(pId)
case *livekit.SignalNodeMessage_EndSession:
signalNode, err := r.getParticipantSignalNode(connectionId)
if err != nil {
logger.Errorw("could not get participant RTC node",
"error", err)
@@ -326,9 +325,61 @@ func (r *RedisRouter) subscribeWorker() {
}
// EndSession can only be initiated on an RTC node, is handled on the signal node
if signalNode == r.currentNode.Id {
resSink := r.getOrCreateMessageChannel(r.responseChannels, pId)
resSink := r.getOrCreateMessageChannel(r.responseChannels, connectionId)
resSink.Close()
}
}
}
}
// worker that consumes RTC channel and processes
func (r *RedisRouter) rtcWorker() {
sub := r.rc.Subscribe(redisCtx, rtcNodeChannel(r.currentNode.Id))
defer func() {
logger.Debugw("finishing redis rtcWorker", "node", r.currentNode.Id)
}()
logger.Debugw("starting redis rtcWorker", "node", r.currentNode.Id)
for r.ctx.Err() == nil {
obj, err := sub.Receive(r.ctx)
if err != nil {
logger.Warnw("error receiving redis message", "error", err)
// TODO: retry? ignore? at a minimum need to sleep here to retry
time.Sleep(time.Second)
continue
}
if obj == nil {
return
}
msg, ok := obj.(*redis.Message)
if !ok {
continue
}
rm := livekit.RTCNodeMessage{}
err = proto.Unmarshal([]byte(msg.Payload), &rm)
pKey := rm.ParticipantKey
switch rmb := rm.Message.(type) {
case *livekit.RTCNodeMessage_StartSession:
logger.Debugw("received router startSession", "node", r.currentNode.Id,
"participant", pKey)
// RTC session should start on this node
err = r.startParticipantRTC(rmb.StartSession, pKey)
if err != nil {
logger.Errorw("could not start participant", "error", err)
}
case *livekit.RTCNodeMessage_Request:
// in the event the current node is an RTC node, push to request channels
reqSink := r.getOrCreateMessageChannel(r.requestChannels, pKey)
err = reqSink.WriteMessage(rmb.Request)
if err != nil {
logger.Errorw("could not write to request channel",
"participant", pKey,
"error", err)
}
}
}
}
+29 -179
View File
@@ -46,32 +46,6 @@ type FakeRouter struct {
result1 string
result2 error
}
GetRequestSinkStub func(string) (routing.MessageSink, error)
getRequestSinkMutex sync.RWMutex
getRequestSinkArgsForCall []struct {
arg1 string
}
getRequestSinkReturns struct {
result1 routing.MessageSink
result2 error
}
getRequestSinkReturnsOnCall map[int]struct {
result1 routing.MessageSink
result2 error
}
GetResponseSourceStub func(string) (routing.MessageSource, error)
getResponseSourceMutex sync.RWMutex
getResponseSourceArgsForCall []struct {
arg1 string
}
getResponseSourceReturns struct {
result1 routing.MessageSource
result2 error
}
getResponseSourceReturnsOnCall map[int]struct {
result1 routing.MessageSource
result2 error
}
ListNodesStub func() ([]*livekit.Node, error)
listNodesMutex sync.RWMutex
listNodesArgsForCall []struct {
@@ -121,18 +95,21 @@ type FakeRouter struct {
startReturnsOnCall map[int]struct {
result1 error
}
StartParticipantSignalStub func(string, string, string) error
StartParticipantSignalStub func(string, string) (routing.MessageSink, routing.MessageSource, error)
startParticipantSignalMutex sync.RWMutex
startParticipantSignalArgsForCall []struct {
arg1 string
arg2 string
arg3 string
}
startParticipantSignalReturns struct {
result1 error
result1 routing.MessageSink
result2 routing.MessageSource
result3 error
}
startParticipantSignalReturnsOnCall map[int]struct {
result1 error
result1 routing.MessageSink
result2 routing.MessageSource
result3 error
}
StopStub func()
stopMutex sync.RWMutex
@@ -341,134 +318,6 @@ func (fake *FakeRouter) GetNodeForRoomReturnsOnCall(i int, result1 string, resul
}{result1, result2}
}
func (fake *FakeRouter) GetRequestSink(arg1 string) (routing.MessageSink, error) {
fake.getRequestSinkMutex.Lock()
ret, specificReturn := fake.getRequestSinkReturnsOnCall[len(fake.getRequestSinkArgsForCall)]
fake.getRequestSinkArgsForCall = append(fake.getRequestSinkArgsForCall, struct {
arg1 string
}{arg1})
stub := fake.GetRequestSinkStub
fakeReturns := fake.getRequestSinkReturns
fake.recordInvocation("GetRequestSink", []interface{}{arg1})
fake.getRequestSinkMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeRouter) GetRequestSinkCallCount() int {
fake.getRequestSinkMutex.RLock()
defer fake.getRequestSinkMutex.RUnlock()
return len(fake.getRequestSinkArgsForCall)
}
func (fake *FakeRouter) GetRequestSinkCalls(stub func(string) (routing.MessageSink, error)) {
fake.getRequestSinkMutex.Lock()
defer fake.getRequestSinkMutex.Unlock()
fake.GetRequestSinkStub = stub
}
func (fake *FakeRouter) GetRequestSinkArgsForCall(i int) string {
fake.getRequestSinkMutex.RLock()
defer fake.getRequestSinkMutex.RUnlock()
argsForCall := fake.getRequestSinkArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeRouter) GetRequestSinkReturns(result1 routing.MessageSink, result2 error) {
fake.getRequestSinkMutex.Lock()
defer fake.getRequestSinkMutex.Unlock()
fake.GetRequestSinkStub = nil
fake.getRequestSinkReturns = struct {
result1 routing.MessageSink
result2 error
}{result1, result2}
}
func (fake *FakeRouter) GetRequestSinkReturnsOnCall(i int, result1 routing.MessageSink, result2 error) {
fake.getRequestSinkMutex.Lock()
defer fake.getRequestSinkMutex.Unlock()
fake.GetRequestSinkStub = nil
if fake.getRequestSinkReturnsOnCall == nil {
fake.getRequestSinkReturnsOnCall = make(map[int]struct {
result1 routing.MessageSink
result2 error
})
}
fake.getRequestSinkReturnsOnCall[i] = struct {
result1 routing.MessageSink
result2 error
}{result1, result2}
}
func (fake *FakeRouter) GetResponseSource(arg1 string) (routing.MessageSource, error) {
fake.getResponseSourceMutex.Lock()
ret, specificReturn := fake.getResponseSourceReturnsOnCall[len(fake.getResponseSourceArgsForCall)]
fake.getResponseSourceArgsForCall = append(fake.getResponseSourceArgsForCall, struct {
arg1 string
}{arg1})
stub := fake.GetResponseSourceStub
fakeReturns := fake.getResponseSourceReturns
fake.recordInvocation("GetResponseSource", []interface{}{arg1})
fake.getResponseSourceMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeRouter) GetResponseSourceCallCount() int {
fake.getResponseSourceMutex.RLock()
defer fake.getResponseSourceMutex.RUnlock()
return len(fake.getResponseSourceArgsForCall)
}
func (fake *FakeRouter) GetResponseSourceCalls(stub func(string) (routing.MessageSource, error)) {
fake.getResponseSourceMutex.Lock()
defer fake.getResponseSourceMutex.Unlock()
fake.GetResponseSourceStub = stub
}
func (fake *FakeRouter) GetResponseSourceArgsForCall(i int) string {
fake.getResponseSourceMutex.RLock()
defer fake.getResponseSourceMutex.RUnlock()
argsForCall := fake.getResponseSourceArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeRouter) GetResponseSourceReturns(result1 routing.MessageSource, result2 error) {
fake.getResponseSourceMutex.Lock()
defer fake.getResponseSourceMutex.Unlock()
fake.GetResponseSourceStub = nil
fake.getResponseSourceReturns = struct {
result1 routing.MessageSource
result2 error
}{result1, result2}
}
func (fake *FakeRouter) GetResponseSourceReturnsOnCall(i int, result1 routing.MessageSource, result2 error) {
fake.getResponseSourceMutex.Lock()
defer fake.getResponseSourceMutex.Unlock()
fake.GetResponseSourceStub = nil
if fake.getResponseSourceReturnsOnCall == nil {
fake.getResponseSourceReturnsOnCall = make(map[int]struct {
result1 routing.MessageSource
result2 error
})
}
fake.getResponseSourceReturnsOnCall[i] = struct {
result1 routing.MessageSource
result2 error
}{result1, result2}
}
func (fake *FakeRouter) ListNodes() ([]*livekit.Node, error) {
fake.listNodesMutex.Lock()
ret, specificReturn := fake.listNodesReturnsOnCall[len(fake.listNodesArgsForCall)]
@@ -725,25 +574,24 @@ func (fake *FakeRouter) StartReturnsOnCall(i int, result1 error) {
}{result1}
}
func (fake *FakeRouter) StartParticipantSignal(arg1 string, arg2 string, arg3 string) error {
func (fake *FakeRouter) StartParticipantSignal(arg1 string, arg2 string) (routing.MessageSink, routing.MessageSource, error) {
fake.startParticipantSignalMutex.Lock()
ret, specificReturn := fake.startParticipantSignalReturnsOnCall[len(fake.startParticipantSignalArgsForCall)]
fake.startParticipantSignalArgsForCall = append(fake.startParticipantSignalArgsForCall, struct {
arg1 string
arg2 string
arg3 string
}{arg1, arg2, arg3})
}{arg1, arg2})
stub := fake.StartParticipantSignalStub
fakeReturns := fake.startParticipantSignalReturns
fake.recordInvocation("StartParticipantSignal", []interface{}{arg1, arg2, arg3})
fake.recordInvocation("StartParticipantSignal", []interface{}{arg1, arg2})
fake.startParticipantSignalMutex.Unlock()
if stub != nil {
return stub(arg1, arg2, arg3)
return stub(arg1, arg2)
}
if specificReturn {
return ret.result1
return ret.result1, ret.result2, ret.result3
}
return fakeReturns.result1
return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3
}
func (fake *FakeRouter) StartParticipantSignalCallCount() int {
@@ -752,40 +600,46 @@ func (fake *FakeRouter) StartParticipantSignalCallCount() int {
return len(fake.startParticipantSignalArgsForCall)
}
func (fake *FakeRouter) StartParticipantSignalCalls(stub func(string, string, string) error) {
func (fake *FakeRouter) StartParticipantSignalCalls(stub func(string, string) (routing.MessageSink, routing.MessageSource, error)) {
fake.startParticipantSignalMutex.Lock()
defer fake.startParticipantSignalMutex.Unlock()
fake.StartParticipantSignalStub = stub
}
func (fake *FakeRouter) StartParticipantSignalArgsForCall(i int) (string, string, string) {
func (fake *FakeRouter) StartParticipantSignalArgsForCall(i int) (string, string) {
fake.startParticipantSignalMutex.RLock()
defer fake.startParticipantSignalMutex.RUnlock()
argsForCall := fake.startParticipantSignalArgsForCall[i]
return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3
return argsForCall.arg1, argsForCall.arg2
}
func (fake *FakeRouter) StartParticipantSignalReturns(result1 error) {
func (fake *FakeRouter) StartParticipantSignalReturns(result1 routing.MessageSink, result2 routing.MessageSource, result3 error) {
fake.startParticipantSignalMutex.Lock()
defer fake.startParticipantSignalMutex.Unlock()
fake.StartParticipantSignalStub = nil
fake.startParticipantSignalReturns = struct {
result1 error
}{result1}
result1 routing.MessageSink
result2 routing.MessageSource
result3 error
}{result1, result2, result3}
}
func (fake *FakeRouter) StartParticipantSignalReturnsOnCall(i int, result1 error) {
func (fake *FakeRouter) StartParticipantSignalReturnsOnCall(i int, result1 routing.MessageSink, result2 routing.MessageSource, result3 error) {
fake.startParticipantSignalMutex.Lock()
defer fake.startParticipantSignalMutex.Unlock()
fake.StartParticipantSignalStub = nil
if fake.startParticipantSignalReturnsOnCall == nil {
fake.startParticipantSignalReturnsOnCall = make(map[int]struct {
result1 error
result1 routing.MessageSink
result2 routing.MessageSource
result3 error
})
}
fake.startParticipantSignalReturnsOnCall[i] = struct {
result1 error
}{result1}
result1 routing.MessageSink
result2 routing.MessageSource
result3 error
}{result1, result2, result3}
}
func (fake *FakeRouter) Stop() {
@@ -874,10 +728,6 @@ func (fake *FakeRouter) Invocations() map[string][][]interface{} {
defer fake.getNodeMutex.RUnlock()
fake.getNodeForRoomMutex.RLock()
defer fake.getNodeForRoomMutex.RUnlock()
fake.getRequestSinkMutex.RLock()
defer fake.getRequestSinkMutex.RUnlock()
fake.getResponseSourceMutex.RLock()
defer fake.getResponseSourceMutex.RUnlock()
fake.listNodesMutex.RLock()
defer fake.listNodesMutex.RUnlock()
fake.onNewParticipantRTCMutex.RLock()
+4
View File
@@ -20,3 +20,7 @@ func GetAvailableNodes(nodes []*livekit.Node) []*livekit.Node {
return IsAvailable(node)
}).([]*livekit.Node)
}
func participantKey(roomName, identity string) string {
return roomName + "|" + identity
}