mirror of
https://github.com/livekit/livekit.git
synced 2026-03-29 09:19:53 +00:00
1
go.mod
1
go.mod
@@ -16,6 +16,7 @@ require (
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||
github.com/jellydator/ttlcache/v3 v3.2.0
|
||||
github.com/jxskiss/base62 v1.1.0
|
||||
github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1
|
||||
github.com/livekit/mediatransportutil v0.0.0-20240416023643-881d3dc5423e
|
||||
|
||||
2
go.sum
2
go.sum
@@ -85,6 +85,8 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/jellydator/ttlcache/v3 v3.2.0 h1:6lqVJ8X3ZaUwvzENqPAobDsXNExfUJd61u++uW8a3LE=
|
||||
github.com/jellydator/ttlcache/v3 v3.2.0/go.mod h1:hi7MGFdMAwZna5n2tuvh63DvFLzVKySzCVW6+0gA2n4=
|
||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
||||
|
||||
@@ -504,7 +504,7 @@ func (r *RoomManager) StartSession(
|
||||
}
|
||||
})
|
||||
participant.OnICEConfigChanged(func(participant types.LocalParticipant, iceConfig *livekit.ICEConfig) {
|
||||
r.iceConfigCache.Put(iceConfigCacheKey{roomName, participant.Identity()}, iceConfig, time.Now())
|
||||
r.iceConfigCache.Put(iceConfigCacheKey{roomName, participant.Identity()}, iceConfig)
|
||||
})
|
||||
|
||||
go r.rtcSessionWorker(room, participant, requestSource)
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/livekit/protocol/livekit"
|
||||
"go.uber.org/atomic"
|
||||
)
|
||||
|
||||
const (
|
||||
iceConfigTTLMin = 5 * time.Minute
|
||||
)
|
||||
|
||||
type iceConfigCacheEntry struct {
|
||||
iceConfig *livekit.ICEConfig
|
||||
modifiedAt time.Time
|
||||
}
|
||||
|
||||
type IceConfigCache[T comparable] struct {
|
||||
lock sync.Mutex
|
||||
ttl time.Duration
|
||||
entries map[T]*iceConfigCacheEntry
|
||||
|
||||
stopped atomic.Bool
|
||||
}
|
||||
|
||||
func NewIceConfigCache[T comparable](ttl time.Duration) *IceConfigCache[T] {
|
||||
icc := &IceConfigCache[T]{
|
||||
entries: make(map[T]*iceConfigCacheEntry),
|
||||
}
|
||||
|
||||
if ttl < iceConfigTTLMin {
|
||||
icc.ttl = iceConfigTTLMin
|
||||
} else {
|
||||
icc.ttl = ttl
|
||||
}
|
||||
|
||||
go icc.pruneWorker()
|
||||
return icc
|
||||
}
|
||||
|
||||
func (icc *IceConfigCache[T]) Stop() {
|
||||
icc.stopped.Store(true)
|
||||
}
|
||||
|
||||
func (icc *IceConfigCache[T]) Put(key T, iceConfig *livekit.ICEConfig, at time.Time) {
|
||||
icc.lock.Lock()
|
||||
defer icc.lock.Unlock()
|
||||
|
||||
icc.entries[key] = &iceConfigCacheEntry{
|
||||
iceConfig: iceConfig,
|
||||
modifiedAt: at,
|
||||
}
|
||||
}
|
||||
|
||||
func (icc *IceConfigCache[T]) Get(key T) *livekit.ICEConfig {
|
||||
icc.lock.Lock()
|
||||
defer icc.lock.Unlock()
|
||||
|
||||
entry, ok := icc.entries[key]
|
||||
if !ok || time.Since(entry.modifiedAt) > icc.ttl {
|
||||
delete(icc.entries, key)
|
||||
return &livekit.ICEConfig{}
|
||||
}
|
||||
|
||||
return entry.iceConfig
|
||||
}
|
||||
|
||||
func (icc *IceConfigCache[T]) pruneWorker() {
|
||||
ticker := time.NewTicker(icc.ttl / 2)
|
||||
defer ticker.Stop()
|
||||
|
||||
for !icc.stopped.Load() {
|
||||
<-ticker.C
|
||||
|
||||
icc.lock.Lock()
|
||||
for key, entry := range icc.entries {
|
||||
if time.Since(entry.modifiedAt) > icc.ttl {
|
||||
delete(icc.entries, key)
|
||||
}
|
||||
}
|
||||
icc.lock.Unlock()
|
||||
}
|
||||
}
|
||||
42
pkg/utils/iceconfigcache.go
Normal file
42
pkg/utils/iceconfigcache.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/jellydator/ttlcache/v3"
|
||||
|
||||
"github.com/livekit/protocol/livekit"
|
||||
)
|
||||
|
||||
const (
|
||||
iceConfigTTLMin = 5 * time.Minute
|
||||
)
|
||||
|
||||
type IceConfigCache[T comparable] struct {
|
||||
c *ttlcache.Cache[T, *livekit.ICEConfig]
|
||||
}
|
||||
|
||||
func NewIceConfigCache[T comparable](ttl time.Duration) *IceConfigCache[T] {
|
||||
cache := ttlcache.New(
|
||||
ttlcache.WithTTL[T, *livekit.ICEConfig](max(ttl, iceConfigTTLMin)),
|
||||
ttlcache.WithDisableTouchOnHit[T, *livekit.ICEConfig](),
|
||||
)
|
||||
go cache.Start()
|
||||
|
||||
return &IceConfigCache[T]{cache}
|
||||
}
|
||||
|
||||
func (icc *IceConfigCache[T]) Stop() {
|
||||
icc.c.Stop()
|
||||
}
|
||||
|
||||
func (icc *IceConfigCache[T]) Put(key T, iceConfig *livekit.ICEConfig) {
|
||||
icc.c.Set(key, iceConfig, ttlcache.DefaultTTL)
|
||||
}
|
||||
|
||||
func (icc *IceConfigCache[T]) Get(key T) *livekit.ICEConfig {
|
||||
if it := icc.c.Get(key); it != nil {
|
||||
return it.Value()
|
||||
}
|
||||
return &livekit.ICEConfig{}
|
||||
}
|
||||
18
pkg/utils/iceconfigcache_test.go
Normal file
18
pkg/utils/iceconfigcache_test.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/livekit/protocol/livekit"
|
||||
)
|
||||
|
||||
func TestIceConfigCache(t *testing.T) {
|
||||
cache := NewIceConfigCache[string](10 * time.Second)
|
||||
t.Cleanup(cache.Stop)
|
||||
|
||||
cache.Put("test", &livekit.ICEConfig{})
|
||||
require.NotNil(t, cache)
|
||||
}
|
||||
Reference in New Issue
Block a user