RedisStore: make UnlockRoom atomic (#1044)

Co-authored-by: David Zhao <dz@livekit.io>
This commit is contained in:
MaxnSter
2022-11-08 15:04:46 +08:00
committed by GitHub
parent c735668f67
commit 7e89ad3fbd

View File

@@ -48,15 +48,22 @@ const (
)
type RedisStore struct {
rc redis.UniversalClient
ctx context.Context
done chan struct{}
rc redis.UniversalClient
unlockScript *redis.Script
ctx context.Context
done chan struct{}
}
func NewRedisStore(rc redis.UniversalClient) *RedisStore {
unlockScript := `if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else return 0
end`
return &RedisStore{
ctx: context.Background(),
rc: rc,
ctx: context.Background(),
rc: rc,
unlockScript: redis.NewScript(unlockScript),
}
}
@@ -244,21 +251,19 @@ func (s *RedisStore) LockRoom(_ context.Context, roomName livekit.RoomName, dura
return "", ErrRoomLockFailed
}
func (s *RedisStore) UnlockRoom(_ context.Context, roomName livekit.RoomName, uid string) error {
func (s *RedisStore) UnlockRoom(ctx context.Context, roomName livekit.RoomName, uid string) error {
key := RoomLockPrefix + string(roomName)
val, err := s.rc.Get(s.ctx, key).Result()
if err == redis.Nil {
// already unlocked
return nil
} else if err != nil {
res, err := s.unlockScript.Run(ctx, s.rc, []string{key}, uid).Result()
if err != nil {
return err
}
if val != uid {
// uid does not match
if i, ok := res.(int64); !ok || i != 1 {
return ErrRoomUnlockFailed
}
return s.rc.Del(s.ctx, key).Err()
return nil
}
func (s *RedisStore) StoreParticipant(_ context.Context, roomName livekit.RoomName, participant *livekit.ParticipantInfo) error {