Files
sub2api/backend/internal/repository/channel_cache.go
T

54 lines
1.3 KiB
Go

package repository
import (
"context"
"log/slog"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
)
const channelCachePubSubKey = "channel_cache_updated"
type channelCache struct {
rdb *redis.Client
}
// NewChannelCache creates the Redis-backed channel cache invalidation bus.
func NewChannelCache(rdb *redis.Client) service.ChannelCachePubSub {
return &channelCache{rdb: rdb}
}
// NotifyUpdate notifies all instances to invalidate their local channel cache.
func (c *channelCache) NotifyUpdate(ctx context.Context) error {
return c.rdb.Publish(ctx, channelCachePubSubKey, "refresh").Err()
}
// SubscribeUpdates subscribes to channel cache invalidation notifications.
func (c *channelCache) SubscribeUpdates(ctx context.Context, handler func()) {
go func() {
pubsub := c.rdb.Subscribe(ctx, channelCachePubSubKey)
defer func() {
if err := pubsub.Close(); err != nil {
slog.Warn("failed to close channel cache subscriber", "error", err)
}
}()
messages := pubsub.Channel()
for {
select {
case <-ctx.Done():
return
case message, ok := <-messages:
if !ok {
slog.Warn("channel cache subscriber stopped", "reason", "channel_closed")
return
}
if message != nil {
handler()
}
}
}
}()
}