mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-15 23:22:59 +08:00
54 lines
1.3 KiB
Go
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()
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
}
|