diff --git a/modules/cache/cache_redis.go b/modules/cache/cache_redis.go index e54887555..4c243b242 100644 --- a/modules/cache/cache_redis.go +++ b/modules/cache/cache_redis.go @@ -12,12 +12,11 @@ import ( "code.gitea.io/gitea/modules/nosql" "code.forgejo.org/go-chi/cache" - "github.com/redis/go-redis/v9" ) // RedisCacher represents a redis cache adapter implementation. type RedisCacher struct { - c redis.UniversalClient + c nosql.RedisClient prefix string hsetName string occupyMode bool diff --git a/modules/nosql/manager.go b/modules/nosql/manager.go index 375c2b5d0..0ba21585f 100644 --- a/modules/nosql/manager.go +++ b/modules/nosql/manager.go @@ -27,8 +27,46 @@ type Manager struct { LevelDBConnections map[string]*levelDBHolder } +// RedisClient is a subset of redis.UniversalClient, it exposes less methods +// to avoid generating machine code for unused methods. New method definitions +// should be copied from the definitions in the Redis library github.com/redis/go-redis. +type RedisClient interface { + // redis.GenericCmdable + Del(ctx context.Context, keys ...string) *redis.IntCmd + Exists(ctx context.Context, keys ...string) *redis.IntCmd + + // redis.ListCmdable + RPush(ctx context.Context, key string, values ...any) *redis.IntCmd + LPop(ctx context.Context, key string) *redis.StringCmd + LLen(ctx context.Context, key string) *redis.IntCmd + + // redis.StringCmdable + Decr(ctx context.Context, key string) *redis.IntCmd + Incr(ctx context.Context, key string) *redis.IntCmd + Set(ctx context.Context, key string, value any, expiration time.Duration) *redis.StatusCmd + Get(ctx context.Context, key string) *redis.StringCmd + + // redis.HashCmdable + HSet(ctx context.Context, key string, values ...any) *redis.IntCmd + HDel(ctx context.Context, key string, fields ...string) *redis.IntCmd + HKeys(ctx context.Context, key string) *redis.StringSliceCmd + + // redis.SetCmdable + SAdd(ctx context.Context, key string, members ...any) *redis.IntCmd + SRem(ctx context.Context, key string, members ...any) *redis.IntCmd + SIsMember(ctx context.Context, key string, member any) *redis.BoolCmd + + // redis.Cmdable + DBSize(ctx context.Context) *redis.IntCmd + FlushDB(ctx context.Context) *redis.StatusCmd + Ping(ctx context.Context) *redis.StatusCmd + + // redis.UniversalClient + Close() error +} + type redisClientHolder struct { - redis.UniversalClient + RedisClient name []string count int64 } diff --git a/modules/nosql/manager_redis.go b/modules/nosql/manager_redis.go index 3c5502f97..79a533bd6 100644 --- a/modules/nosql/manager_redis.go +++ b/modules/nosql/manager_redis.go @@ -39,11 +39,11 @@ func (m *Manager) CloseRedisClient(connection string) error { for _, name := range client.name { delete(m.RedisConnections, name) } - return client.UniversalClient.Close() + return client.RedisClient.Close() } // GetRedisClient gets a redis client for a particular connection -func (m *Manager) GetRedisClient(connection string) (client redis.UniversalClient) { +func (m *Manager) GetRedisClient(connection string) (client RedisClient) { // Because we want associate any goroutines created by this call to the main nosqldb context we need to // wrap this in a goroutine labelled with the nosqldb context done := make(chan struct{}) @@ -67,7 +67,7 @@ func (m *Manager) GetRedisClient(connection string) (client redis.UniversalClien return client } -func (m *Manager) getRedisClient(connection string) redis.UniversalClient { +func (m *Manager) getRedisClient(connection string) RedisClient { m.mutex.Lock() defer m.mutex.Unlock() client, ok := m.RedisConnections[connection] @@ -102,24 +102,24 @@ func (m *Manager) getRedisClient(connection string) redis.UniversalClient { opts.TLSConfig = tlsConfig fallthrough case "redis+sentinel": - client.UniversalClient = redis.NewFailoverClient(opts.Failover()) + client.RedisClient = redis.NewFailoverClient(opts.Failover()) case "redis+clusters": fallthrough case "rediss+cluster": opts.TLSConfig = tlsConfig fallthrough case "redis+cluster": - client.UniversalClient = redis.NewClusterClient(opts.Cluster()) + client.RedisClient = redis.NewClusterClient(opts.Cluster()) case "redis+socket": simpleOpts := opts.Simple() simpleOpts.Network = "unix" simpleOpts.Addr = path.Join(uri.Host, uri.Path) - client.UniversalClient = redis.NewClient(simpleOpts) + client.RedisClient = redis.NewClient(simpleOpts) case "rediss": opts.TLSConfig = tlsConfig fallthrough case "redis": - client.UniversalClient = redis.NewClient(opts.Simple()) + client.RedisClient = redis.NewClient(opts.Simple()) default: return nil } diff --git a/modules/queue/base_redis.go b/modules/queue/base_redis.go index 14931b62c..62df30f68 100644 --- a/modules/queue/base_redis.go +++ b/modules/queue/base_redis.go @@ -16,7 +16,7 @@ import ( ) type baseRedis struct { - client redis.UniversalClient + client nosql.RedisClient isUnique bool cfg *BaseConfig prefix string @@ -26,7 +26,7 @@ type baseRedis struct { var _ baseQueue = (*baseRedis)(nil) -func newBaseRedisGeneric(cfg *BaseConfig, unique bool, client redis.UniversalClient) (baseQueue, error) { +func newBaseRedisGeneric(cfg *BaseConfig, unique bool, client nosql.RedisClient) (baseQueue, error) { if client == nil { client = nosql.GetManager().GetRedisClient(cfg.ConnStr) } diff --git a/modules/session/redis.go b/modules/session/redis.go index 69cf6b1a4..230b50108 100644 --- a/modules/session/redis.go +++ b/modules/session/redis.go @@ -26,12 +26,11 @@ import ( "code.gitea.io/gitea/modules/nosql" "code.forgejo.org/go-chi/session" - "github.com/redis/go-redis/v9" ) // RedisStore represents a redis session store implementation. type RedisStore struct { - c redis.UniversalClient + c nosql.RedisClient prefix, sid string duration time.Duration lock sync.RWMutex @@ -39,7 +38,7 @@ type RedisStore struct { } // NewRedisStore creates and returns a redis session store. -func NewRedisStore(c redis.UniversalClient, prefix, sid string, dur time.Duration, kv map[any]any) *RedisStore { +func NewRedisStore(c nosql.RedisClient, prefix, sid string, dur time.Duration, kv map[any]any) *RedisStore { return &RedisStore{ c: c, prefix: prefix, @@ -106,7 +105,7 @@ func (s *RedisStore) Flush() error { // RedisProvider represents a redis session provider implementation. type RedisProvider struct { - c redis.UniversalClient + c nosql.RedisClient duration time.Duration prefix string }