Merge pull request 'chore: Only implement used API of Redis client' (#5173) from gusted/forgejo-redis-binary-size into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5173
Reviewed-by: Otto <otto@codeberg.org>
This commit is contained in:
Gusted 2024-08-31 23:08:17 +00:00
commit 500e0e8602
5 changed files with 52 additions and 16 deletions

View file

@ -12,12 +12,11 @@ import (
"code.gitea.io/gitea/modules/nosql" "code.gitea.io/gitea/modules/nosql"
"code.forgejo.org/go-chi/cache" "code.forgejo.org/go-chi/cache"
"github.com/redis/go-redis/v9"
) )
// RedisCacher represents a redis cache adapter implementation. // RedisCacher represents a redis cache adapter implementation.
type RedisCacher struct { type RedisCacher struct {
c redis.UniversalClient c nosql.RedisClient
prefix string prefix string
hsetName string hsetName string
occupyMode bool occupyMode bool

View file

@ -27,8 +27,46 @@ type Manager struct {
LevelDBConnections map[string]*levelDBHolder 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 { type redisClientHolder struct {
redis.UniversalClient RedisClient
name []string name []string
count int64 count int64
} }

View file

@ -39,11 +39,11 @@ func (m *Manager) CloseRedisClient(connection string) error {
for _, name := range client.name { for _, name := range client.name {
delete(m.RedisConnections, name) delete(m.RedisConnections, name)
} }
return client.UniversalClient.Close() return client.RedisClient.Close()
} }
// GetRedisClient gets a redis client for a particular connection // 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 // 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 // wrap this in a goroutine labelled with the nosqldb context
done := make(chan struct{}) done := make(chan struct{})
@ -67,7 +67,7 @@ func (m *Manager) GetRedisClient(connection string) (client redis.UniversalClien
return client return client
} }
func (m *Manager) getRedisClient(connection string) redis.UniversalClient { func (m *Manager) getRedisClient(connection string) RedisClient {
m.mutex.Lock() m.mutex.Lock()
defer m.mutex.Unlock() defer m.mutex.Unlock()
client, ok := m.RedisConnections[connection] client, ok := m.RedisConnections[connection]
@ -102,24 +102,24 @@ func (m *Manager) getRedisClient(connection string) redis.UniversalClient {
opts.TLSConfig = tlsConfig opts.TLSConfig = tlsConfig
fallthrough fallthrough
case "redis+sentinel": case "redis+sentinel":
client.UniversalClient = redis.NewFailoverClient(opts.Failover()) client.RedisClient = redis.NewFailoverClient(opts.Failover())
case "redis+clusters": case "redis+clusters":
fallthrough fallthrough
case "rediss+cluster": case "rediss+cluster":
opts.TLSConfig = tlsConfig opts.TLSConfig = tlsConfig
fallthrough fallthrough
case "redis+cluster": case "redis+cluster":
client.UniversalClient = redis.NewClusterClient(opts.Cluster()) client.RedisClient = redis.NewClusterClient(opts.Cluster())
case "redis+socket": case "redis+socket":
simpleOpts := opts.Simple() simpleOpts := opts.Simple()
simpleOpts.Network = "unix" simpleOpts.Network = "unix"
simpleOpts.Addr = path.Join(uri.Host, uri.Path) simpleOpts.Addr = path.Join(uri.Host, uri.Path)
client.UniversalClient = redis.NewClient(simpleOpts) client.RedisClient = redis.NewClient(simpleOpts)
case "rediss": case "rediss":
opts.TLSConfig = tlsConfig opts.TLSConfig = tlsConfig
fallthrough fallthrough
case "redis": case "redis":
client.UniversalClient = redis.NewClient(opts.Simple()) client.RedisClient = redis.NewClient(opts.Simple())
default: default:
return nil return nil
} }

View file

@ -16,7 +16,7 @@ import (
) )
type baseRedis struct { type baseRedis struct {
client redis.UniversalClient client nosql.RedisClient
isUnique bool isUnique bool
cfg *BaseConfig cfg *BaseConfig
prefix string prefix string
@ -26,7 +26,7 @@ type baseRedis struct {
var _ baseQueue = (*baseRedis)(nil) 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 { if client == nil {
client = nosql.GetManager().GetRedisClient(cfg.ConnStr) client = nosql.GetManager().GetRedisClient(cfg.ConnStr)
} }

View file

@ -26,12 +26,11 @@ import (
"code.gitea.io/gitea/modules/nosql" "code.gitea.io/gitea/modules/nosql"
"code.forgejo.org/go-chi/session" "code.forgejo.org/go-chi/session"
"github.com/redis/go-redis/v9"
) )
// RedisStore represents a redis session store implementation. // RedisStore represents a redis session store implementation.
type RedisStore struct { type RedisStore struct {
c redis.UniversalClient c nosql.RedisClient
prefix, sid string prefix, sid string
duration time.Duration duration time.Duration
lock sync.RWMutex lock sync.RWMutex
@ -39,7 +38,7 @@ type RedisStore struct {
} }
// NewRedisStore creates and returns a redis session store. // 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{ return &RedisStore{
c: c, c: c,
prefix: prefix, prefix: prefix,
@ -106,7 +105,7 @@ func (s *RedisStore) Flush() error {
// RedisProvider represents a redis session provider implementation. // RedisProvider represents a redis session provider implementation.
type RedisProvider struct { type RedisProvider struct {
c redis.UniversalClient c nosql.RedisClient
duration time.Duration duration time.Duration
prefix string prefix string
} }