Files
2026-06-15 22:46:12 +08:00

83 lines
1.6 KiB
Go

package store
import (
"context"
"encoding/json"
"errors"
"fmt"
"time"
"github.com/redis/go-redis/v9"
"synctv/server/internal/room"
)
var ErrNotFound = errors.New("room not found")
type RedisStore struct {
client *redis.Client
ttl time.Duration
}
func NewRedis(addr, password string, db int, ttl time.Duration) *RedisStore {
return &RedisStore{
client: redis.NewClient(&redis.Options{
Addr: addr,
Password: password,
DB: db,
}),
ttl: ttl,
}
}
func (s *RedisStore) Ping(ctx context.Context) error {
return s.client.Ping(ctx).Err()
}
func (s *RedisStore) Close() error {
return s.client.Close()
}
func (s *RedisStore) GetRoom(ctx context.Context, code string) (room.Room, error) {
b, err := s.client.Get(ctx, roomKey(code)).Bytes()
if errors.Is(err, redis.Nil) {
return room.Room{}, ErrNotFound
}
if err != nil {
return room.Room{}, err
}
var r room.Room
if err := json.Unmarshal(b, &r); err != nil {
return room.Room{}, err
}
return r, nil
}
func (s *RedisStore) SaveRoom(ctx context.Context, r room.Room) error {
r.UpdatedAt = room.NowMS()
r.ExpiresAt = time.Now().Add(s.ttl).UnixMilli()
b, err := json.Marshal(r)
if err != nil {
return err
}
return s.client.Set(ctx, roomKey(r.Code), b, s.ttl).Err()
}
func (s *RedisStore) CreateRoom(ctx context.Context, r room.Room) error {
b, err := json.Marshal(r)
if err != nil {
return err
}
ok, err := s.client.SetNX(ctx, roomKey(r.Code), b, s.ttl).Result()
if err != nil {
return err
}
if !ok {
return errors.New("room code already exists")
}
return nil
}
func roomKey(code string) string {
return fmt.Sprintf("room:%s", code)
}