优化结构

This commit is contained in:
Yvan
2026-08-27 16:20:37 +08:00
parent 001e39da50
commit 653414a1da
54 changed files with 1257 additions and 3450 deletions
+38 -10
View File
@@ -19,6 +19,7 @@ import (
datatask "kra/internal/data/task"
"kra/internal/integration/runtimeconfig"
"kra/internal/integration/storage"
"kra/pkg/database/migration"
"kra/pkg/module"
)
@@ -47,11 +48,11 @@ type Data struct {
initMu sync.Mutex
configMu sync.Mutex
databaseReady atomic.Bool
gormDB *reloadableDB
redis *reloadableRedis
gormDB *reloadable[*gorm.DB]
redis *reloadable[redis.UniversalClient]
redisListMu sync.RWMutex
redisList map[string]redis.UniversalClient
mongo *reloadableMongo
mongo *reloadable[*mongo.Client]
runtime *config.Store
integrations *runtimeconfig.Store
storage *storage.Reloadable
@@ -71,7 +72,7 @@ func (d *Data) DB() *gorm.DB {
if d == nil || d.gormDB == nil {
return nil
}
return d.gormDB.DB()
return d.gormDB.load()
}
// DatabaseReady reports whether the configured primary database has been
@@ -103,7 +104,7 @@ func (d *Data) IntegrationRuntime() *runtimeconfig.Store {
// the system export module.
func (d *Data) Database(name string) (*gorm.DB, error) {
if name == "" {
return d.gormDB.DB(), nil
return d.gormDB.load(), nil
}
d.dbListMu.RLock()
db := d.dbList[name]
@@ -306,11 +307,11 @@ func NewData(runtime *config.Store, appLogger *slog.Logger, storageManager *stor
}
}
if !usingFallback {
storageConfig, storageErr := resolveStorageIntegrationConfig(db, admin.Storage)
storageConfig, storageErr := dataintegration.ResolveStorageConfig(db, admin.Storage)
if storageErr != nil {
return nil, nil, fmt.Errorf("load storage integration configuration: %w", storageErr)
}
emailConfig, emailErr := resolveEmailIntegrationConfig(db, admin.Email)
emailConfig, emailErr := dataintegration.ResolveEmailConfig(db, admin.Email)
if emailErr != nil {
return nil, nil, fmt.Errorf("load email integration configuration: %w", emailErr)
}
@@ -337,7 +338,7 @@ func NewData(runtime *config.Store, appLogger *slog.Logger, storageManager *stor
return nil, nil, fmt.Errorf("storage manager is nil")
}
useRedis := admin != nil && admin.System != nil && admin.System.UseRedis
d.redis = newReloadableRedis(openRedis(c.Redis, useRedis, appLogger))
d.redis = newReloadable(openRedis(c.Redis, useRedis, appLogger), closeRedisClient)
useRedisList := useRedis && admin.System.UseMultipoint
d.redisList = openRedisList(c.RedisList, useRedisList, appLogger)
useMongo := admin != nil && admin.System != nil && admin.System.UseMongo
@@ -346,7 +347,7 @@ func NewData(runtime *config.Store, appLogger *slog.Logger, storageManager *stor
appLogger.Error("mongo unavailable", "mod", "mongo", "error", err)
mongoClient = nil
}
d.mongo = newReloadableMongo(mongoClient)
d.mongo = newReloadable(mongoClient, closeMongoClient)
initialized = true
return d, cleanup, nil
}
@@ -437,8 +438,35 @@ func (d *Data) replaceRedisList(clients map[string]redis.UniversalClient) {
}
}
// replacePrimaryDB swaps in a hot-reloaded pool, attaching the row-level data
// scope callbacks before the handle becomes readable.
func (d *Data) replacePrimaryDB(db *gorm.DB) {
registerDataScopeCallbacks(db, d.enqueueDataScopeAudit)
d.gormDB.replace(db)
}
func (d *Data) activateDatabase(db *gorm.DB, config *config.Database) {
d.gormDB.replace(db, d.enqueueDataScopeAudit)
d.replacePrimaryDB(db)
d.runtime.UpdateDatabase(config)
d.databaseReady.Store(true)
}
// migrateAll is the single data-layer migration entry point. Every module
// must register its migrations through the application catalog; there is no
// hidden system/payment fallback that could silently omit a new module.
func migrateAll(db *gorm.DB, catalog module.Catalog) error {
return migration.Run(db, catalog.MigrationSteps())
}
// loadIntegrationRuntime republishes the database-backed integration
// configuration into the live store the long-lived adapters read.
func (d *Data) loadIntegrationRuntime(db *gorm.DB) error {
configs, err := dataintegration.ReadRuntime(db)
if err != nil {
return err
}
if d.integrations != nil {
d.integrations.Replace(configs)
}
return nil
}