feat(core): implement cordis configuration extension and migrate all plugins

This commit is contained in:
ryan
2026-08-29 10:53:53 +08:00
parent b43c429544
commit ed8491addf
74 changed files with 1354 additions and 1145 deletions
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
package cache
// RedisConfig declares the configuration read by the Redis cache provider.
type RedisConfig struct {
Enabled bool `config:"enabled" env:"REDIS_ENABLED" default:"false" autoEnable:"REDIS_ADDR"`
Addrs []string `config:"addrs" env:"REDIS_ADDR"`
Username string `config:"username" env:"REDIS_USERNAME"`
Password string `config:"password" env:"REDIS_PASSWORD" secret:"true"`
DB int `config:"db" env:"REDIS_DB"`
ClusterMode bool `config:"cluster_mode" env:"REDIS_CLUSTER_MODE"`
MasterName string `config:"master_name" env:"REDIS_MASTER_NAME"`
KeyPrefix string `config:"key_prefix" env:"REDIS_KEY_PREFIX"`
PoolSize int `config:"pool_size" env:"REDIS_POOL_SIZE"`
MinIdleConn int `config:"min_idle_conn" env:"REDIS_MIN_IDLE_CONN"`
DialTimeout int `config:"dial_timeout" env:"REDIS_DIAL_TIMEOUT"`
ReadTimeout int `config:"read_timeout" env:"REDIS_READ_TIMEOUT"`
WriteTimeout int `config:"write_timeout" env:"REDIS_WRITE_TIMEOUT"`
MaxRetries int `config:"max_retries" env:"REDIS_MAX_RETRIES"`
PoolTimeout int `config:"pool_timeout" env:"REDIS_POOL_TIMEOUT"`
ConnMaxIdleTime int `config:"conn_max_idle_time" env:"REDIS_CONN_MAX_IDLE_TIME"`
MaintNotifications bool `config:"maint_notifications" env:"REDIS_MAINT_NOTIFICATIONS" default:"false"`
}
+18 -1
View File
@@ -77,13 +77,30 @@ func (p *Plugin) Name() string {
return "cache"
}
// DeclareConfig declares the configuration bindings consumed by this plugin.
func (p *Plugin) DeclareConfig() []core.ConfigBinding {
return []core.ConfigBinding{
{Prefix: "redis", Target: &RedisConfig{}},
}
}
// ConfigEnabled gates plugin activation based on whether Redis is enabled.
func (p *Plugin) ConfigEnabled(view core.ConfigView) bool {
return view.Bool("redis.enabled", false)
}
// Apply mounts the multi-layer cache service into the Context.
func (p *Plugin) Apply(ctx *core.Context) error {
var cfg RedisConfig
if err := ctx.Config().Bind("redis", &cfg); err != nil {
return err
}
redisClient := p.redisClient
if redisClient == nil {
if Redis == nil {
var err error
redisClient, err = InitRedis()
redisClient, err = InitRedisWithConfig(cfg)
if err != nil {
return err
}
+4 -2
View File
@@ -32,9 +32,11 @@ func TestCachePluginOperations(t *testing.T) {
cache.WithKeyPrefix("app:"),
cache.WithRAMCapacity(500),
)
assert.Equal(t, "cache", p.Name())
ctx := core.NewContext(context.Background())
ctx.Config().SetSource(core.NewMapSource(map[string]any{
"redis.enabled": true,
}))
require.NoError(t, ctx.Config().Resolve())
require.NoError(t, p.Apply(ctx))
svc, err := core.Inject[contracts.CacheService](ctx)
+26 -7
View File
@@ -4,12 +4,12 @@
package cache
import (
"Wavelet/pkg/config"
"context"
"encoding/json"
"fmt"
"log"
"strings"
"sync"
"time"
"github.com/redis/go-redis/extra/redisotel/v9"
@@ -18,18 +18,37 @@ import (
"go.opentelemetry.io/otel/attribute"
)
// Redis 全局 Redis 客户端实例
var Redis redis.UniversalClient
var (
// Redis 全局 Redis 客户端实例
Redis redis.UniversalClient
// InitRedis 初始化全局/默认 Redis 客户端实例
func InitRedis() (redis.UniversalClient, error) {
cfg := config.Config.Redis
keyPrefixMu sync.RWMutex
keyPrefix string
)
// SetKeyPrefix sets the package-level key prefix.
func SetKeyPrefix(prefix string) {
keyPrefixMu.Lock()
defer keyPrefixMu.Unlock()
keyPrefix = prefix
}
// GetKeyPrefix returns the package-level key prefix.
func GetKeyPrefix() string {
keyPrefixMu.RLock()
defer keyPrefixMu.RUnlock()
return keyPrefix
}
// InitRedisWithConfig initializes the Redis client using the provided RedisConfig.
func InitRedisWithConfig(cfg RedisConfig) (redis.UniversalClient, error) {
if !cfg.Enabled {
log.Println("[Redis] is disabled, skipping Redis initialization")
return nil, nil
}
SetKeyPrefix(cfg.KeyPrefix)
var client redis.UniversalClient
if cfg.ClusterMode {
@@ -114,7 +133,7 @@ func redisMaintNotificationsConfig(enabled bool) *maintnotifications.Config {
// PrefixedKey 返回带前缀的 Key
func PrefixedKey(key string) string {
prefix := config.Config.Redis.KeyPrefix
prefix := GetKeyPrefix()
if prefix == "" {
return key
}