diff --git a/pkg/service/roommanager.go b/pkg/service/roommanager.go index 4d0b7d1a0..a102578dc 100644 --- a/pkg/service/roommanager.go +++ b/pkg/service/roommanager.go @@ -312,11 +312,11 @@ func (r *RoomManager) StartSession(ctx context.Context, roomName livekit.RoomNam // create the actual room object, to be used on RTC node func (r *RoomManager) getOrCreateRoom(ctx context.Context, roomName livekit.RoomName) (*rtc.Room, error) { r.lock.RLock() - room := r.rooms[roomName] + lastSeenRoom := r.rooms[roomName] r.lock.RUnlock() - if room != nil && room.Hold() { - return room, nil + if lastSeenRoom != nil && lastSeenRoom.Hold() { + return lastSeenRoom, nil } // create new room, get details first @@ -325,14 +325,25 @@ func (r *RoomManager) getOrCreateRoom(ctx context.Context, roomName livekit.Room return nil, err } + r.lock.Lock() + + currentRoom := r.rooms[roomName] + for currentRoom != lastSeenRoom { + r.lock.Unlock() + if currentRoom.Hold() { + return currentRoom, nil + } else { + lastSeenRoom = currentRoom + r.lock.Lock() + currentRoom = r.rooms[roomName] + } + } + // construct ice servers - room = rtc.NewRoom(ri, *r.rtcConfig, &r.config.Audio, r.telemetry) - room.Hold() + newRoom := rtc.NewRoom(ri, *r.rtcConfig, &r.config.Audio, r.telemetry) - r.telemetry.RoomStarted(ctx, room.Room) - - room.OnClose(func() { - r.telemetry.RoomEnded(ctx, room.Room) + newRoom.OnClose(func() { + r.telemetry.RoomEnded(ctx, newRoom.Room) if err := r.DeleteRoom(ctx, roomName); err != nil { logger.Errorw("could not delete room", err) } @@ -340,13 +351,13 @@ func (r *RoomManager) getOrCreateRoom(ctx context.Context, roomName livekit.Room logger.Infow("room closed") }) - room.OnMetadataUpdate(func(metadata string) { - if err := r.roomStore.StoreRoom(ctx, room.Room); err != nil { + newRoom.OnMetadataUpdate(func(metadata string) { + if err := r.roomStore.StoreRoom(ctx, newRoom.Room); err != nil { logger.Errorw("could not handle metadata update", err) } }) - room.OnParticipantChanged(func(p types.LocalParticipant) { + newRoom.OnParticipantChanged(func(p types.LocalParticipant) { if p.State() != livekit.ParticipantInfo_DISCONNECTED { if err := r.roomStore.StoreParticipant(ctx, roomName, p.ToProto()); err != nil { logger.Errorw("could not handle participant change", err) @@ -354,11 +365,15 @@ func (r *RoomManager) getOrCreateRoom(ctx context.Context, roomName livekit.Room } }) - r.lock.Lock() - r.rooms[roomName] = room + r.rooms[roomName] = newRoom + r.lock.Unlock() - return room, nil + newRoom.Hold() + + r.telemetry.RoomStarted(ctx, newRoom.Room) + + return newRoom, nil } // manages an RTC session for a participant, runs on the RTC node