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
@@ -0,0 +1,28 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
package driver_asynq_worker
type queueConfig struct {
Name string `config:"name"`
Priority int `config:"priority"`
}
type workerConfig struct {
Concurrency int `config:"concurrency" env:"WORKER_CONCURRENCY" default:"10"`
StrictPriority bool `config:"strict_priority" env:"WORKER_STRICT_PRIORITY" default:"false"`
Queues []queueConfig `config:"queues"`
}
type redisWorkerConfig 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"`
MaintNotifications bool `config:"maint_notifications" env:"REDIS_MAINT_NOTIFICATIONS" default:"false"`
}
@@ -4,6 +4,7 @@
package driver_asynq_worker
import (
"Wavelet/pkg/idgen"
"Wavelet/pkg/testhelper"
"context"
"errors"
@@ -22,6 +23,10 @@ import (
"gorm.io/gorm"
)
func init() {
_ = idgen.Init(1)
}
type mockDBService struct {
db *gorm.DB
}
@@ -108,10 +108,44 @@ func (p *Plugin) Name() string {
return "driver_asynq_worker"
}
// DeclareConfig declares configuration bindings consumed by the Asynq worker driver.
func (p *Plugin) DeclareConfig() []core.ConfigBinding {
return []core.ConfigBinding{
{Prefix: "worker", Target: &workerConfig{}},
{Prefix: "redis", Target: &redisWorkerConfig{}},
}
}
// ConfigEnabled gates plugin activation when Redis is enabled.
func (p *Plugin) ConfigEnabled(view core.ConfigView) bool {
return view.Bool("redis.enabled", false)
}
// Apply mounts the Asynq Worker driver into the micro-kernel Context.
func (p *Plugin) Apply(ctx *core.Context) error {
var wCfg workerConfig
_ = ctx.Config().Bind("worker", &wCfg)
var rCfg redisWorkerConfig
_ = ctx.Config().Bind("redis", &rCfg)
p.mu.Lock()
p.coreCtx = ctx
if p.concurrency == defaultConcurrency && wCfg.Concurrency > 0 {
p.concurrency = wCfg.Concurrency
}
p.strictPriority = wCfg.StrictPriority
if len(p.queues) == 1 && p.queues["default"] == 1 && len(wCfg.Queues) > 0 {
qMap := make(map[string]int, len(wCfg.Queues))
for _, q := range wCfg.Queues {
qMap[q.Name] = q.Priority
}
p.queues = qMap
}
if p.redisOpt == nil {
p.redisOpt = NewRedisConnOptWithConfig(rCfg)
}
RedisOpt = p.redisOpt
ResetAsynqClient()
p.mu.Unlock()
// 0. Bind DBService
@@ -4,7 +4,6 @@
package driver_asynq_worker
import (
"Wavelet/pkg/config"
"sync"
"github.com/hibiken/asynq"
@@ -72,8 +71,11 @@ func GetAsynqClient() *asynq.Client {
return AsynqClient
}
opt := NewRedisConnOpt()
RedisOpt = opt
opt := RedisOpt
if opt == nil {
opt = NewRedisConnOpt()
RedisOpt = opt
}
AsynqClient = asynq.NewClient(opt)
return AsynqClient
}
@@ -88,9 +90,33 @@ func ResetAsynqClient() {
}
}
var (
keyPrefixMu sync.RWMutex
keyPrefix string
)
// SetKeyPrefix sets the redis key prefix for queue names.
func SetKeyPrefix(prefix string) {
keyPrefixMu.Lock()
defer keyPrefixMu.Unlock()
keyPrefix = prefix
}
// GetKeyPrefix returns the redis key prefix for queue names.
func GetKeyPrefix() string {
keyPrefixMu.RLock()
defer keyPrefixMu.RUnlock()
return keyPrefix
}
// NewRedisConnOpt 根据配置返回对应的 asynq Redis 连接选项
func NewRedisConnOpt() asynq.RedisConnOpt {
cfg := config.Config.Redis
return NewRedisConnOptWithConfig(redisWorkerConfig{})
}
// NewRedisConnOptWithConfig returns the asynq RedisConnOpt based on the provided configuration.
func NewRedisConnOptWithConfig(cfg redisWorkerConfig) asynq.RedisConnOpt {
SetKeyPrefix(cfg.KeyPrefix)
addrs := cfg.Addrs
if cfg.ClusterMode {
@@ -135,7 +161,7 @@ func NewRedisConnOpt() asynq.RedisConnOpt {
// PrefixedQueue 返回带前缀的队列名,用于 Cluster 模式隔离
func PrefixedQueue(queue string) string {
prefix := config.Config.Redis.KeyPrefix
prefix := GetKeyPrefix()
if prefix == "" {
return queue
}
@@ -4,7 +4,6 @@
package driver_asynq_worker
import (
"Wavelet/pkg/config"
"testing"
"github.com/redis/go-redis/v9/maintnotifications"
@@ -42,17 +41,17 @@ func TestMaintNotificationsConfig(t *testing.T) {
}
func TestPrefixedQueue(t *testing.T) {
oldPrefix := config.Config.Redis.KeyPrefix
oldPrefix := GetKeyPrefix()
defer func() {
config.Config.Redis.KeyPrefix = oldPrefix
SetKeyPrefix(oldPrefix)
}()
config.Config.Redis.KeyPrefix = "test:"
SetKeyPrefix("test:")
if got := PrefixedQueue("default"); got != "test:default" {
t.Fatalf("PrefixedQueue() = %q, want %q", got, "test:default")
}
config.Config.Redis.KeyPrefix = ""
SetKeyPrefix("")
if got := PrefixedQueue("default"); got != "default" {
t.Fatalf("PrefixedQueue() = %q, want %q", got, "default")
}