优化结构

This commit is contained in:
Yvan
2026-08-22 22:34:33 +08:00
parent 0126995090
commit b18baf1547
26 changed files with 501 additions and 80 deletions
+21 -3
View File
@@ -382,6 +382,12 @@ func (d *Data) reloadConfig(ctx context.Context) error {
}
useRedis := next.Admin.System != nil && next.Admin.System.UseRedis
candidateRedis := openRedis(next.Data.Redis, useRedis, d.logger())
candidateRedisAccepted := false
defer func() {
if !candidateRedisAccepted && candidateRedis != nil {
_ = candidateRedis.Close()
}
}()
useMongo := next.Admin.System != nil && next.Admin.System.UseMongo
candidateMongo, mongoErr := openMongo(next.Data.Mongo, useMongo)
if mongoErr != nil {
@@ -397,6 +403,16 @@ func (d *Data) reloadConfig(ctx context.Context) error {
if err != nil {
return err
}
candidateDBListAccepted := false
defer func() {
if !candidateDBListAccepted {
closeDatabaseList(candidateDBList)
}
}()
integrationConfigs, err := readIntegrationRuntime(candidateDB)
if err != nil {
return fmt.Errorf("reload integration runtime: %w", err)
}
d.gormDB.replace(candidateDB, d.enqueueDataScopeAudit)
d.databaseReady.Store(databaseReady)
@@ -409,14 +425,16 @@ func (d *Data) reloadConfig(ctx context.Context) error {
d.mongo.replace(candidateMongo)
mongoAccepted = true
}
closeCandidate = false
candidateDBListAccepted = true
candidateRedisAccepted = true
d.runtime.Replace(next.Data, next.Admin)
if err = d.loadIntegrationRuntime(candidateDB); err != nil {
return fmt.Errorf("reload integration runtime: %w", err)
if d.integrations != nil {
d.integrations.Replace(integrationConfigs)
}
if d.storage != nil {
d.storage.Replace(candidateStorage)
}
closeCandidate = false
return nil
}
+30 -11
View File
@@ -176,6 +176,34 @@ func NewData(runtime *conf.Runtime, appLogger *slog.Logger, storageManager *stor
c.Database = &conf.Data_Database{}
}
d := &Data{runtime: runtime, integrations: runtimeconfig.NewStore(), appLogger: appLogger, storage: storageManager, catalog: catalog}
var stopConfigWatcher func()
var cleanupOnce sync.Once
cleanup := func() {
cleanupOnce.Do(func() {
if stopConfigWatcher != nil {
stopConfigWatcher()
}
if d.auditLog != nil {
d.auditLog.Close()
}
if d.gormDB != nil {
d.gormDB.close()
}
closeDatabaseList(d.dbList)
if d.redis != nil {
d.redis.close()
}
if d.mongo != nil {
d.mongo.close()
}
})
}
initialized := false
defer func() {
if !initialized {
cleanup()
}
}()
usingFallback := !databaseConnectionConfigured(c.Database)
var db *gorm.DB
var err error
@@ -199,8 +227,6 @@ func NewData(runtime *conf.Runtime, appLogger *slog.Logger, storageManager *stor
d.auditLog = newDataScopeAuditWriter(d, appLogger)
d.dbList, err = openDatabaseList(c.DatabaseList, appLogger)
if err != nil {
d.auditLog.Close()
d.gormDB.close()
return nil, nil, err
}
for _, item := range d.dbList {
@@ -256,15 +282,8 @@ func NewData(runtime *conf.Runtime, appLogger *slog.Logger, storageManager *stor
mongoClient = nil
}
d.mongo = newReloadableMongo(mongoClient)
stopConfigWatcher := d.watchConfig()
cleanup := func() {
stopConfigWatcher()
d.auditLog.Close()
d.gormDB.close()
closeDatabaseList(d.dbList)
d.redis.close()
d.mongo.close()
}
stopConfigWatcher = d.watchConfig()
initialized = true
return d, cleanup, nil
}
+7 -3
View File
@@ -209,7 +209,12 @@ func (d *Data) InitializeDatabase(ctx context.Context, input *system.DatabaseCon
if err := d.persistDatabaseConfig(config, signingKey); err != nil {
return fmt.Errorf("persist database configuration: %w", err)
}
integrationConfigs, err := readIntegrationRuntime(candidate)
if err != nil {
return fmt.Errorf("initialize integration runtime: %w", err)
}
d.activateDatabase(candidate, config)
activated = true
currentData, currentAdmin := d.runtime.Values()
if currentAdmin == nil {
currentAdmin = &conf.AdminBackend{}
@@ -221,9 +226,8 @@ func (d *Data) InitializeDatabase(ctx context.Context, input *system.DatabaseCon
currentAdmin.Storage = storageConfig
currentAdmin.Email = emailConfig
d.runtime.Replace(currentData, currentAdmin)
if err = d.loadIntegrationRuntime(candidate); err != nil {
return fmt.Errorf("initialize integration runtime: %w", err)
if d.integrations != nil {
d.integrations.Replace(integrationConfigs)
}
activated = true
return nil
}
@@ -27,10 +27,6 @@ func (ConfigPO) TableName() string { return "sys_integration_configs" }
type integrationConfigRepo struct{ data Provider }
type integrationRuntimeProvider interface {
IntegrationRuntime() *runtimeconfig.Store
}
func NewIntegrationConfigRepo(data Provider) integrationbiz.IntegrationConfigRepo {
return &integrationConfigRepo{data: data}
}
@@ -110,8 +106,8 @@ func (r *integrationConfigRepo) publish(kind, provider string, enabled bool, val
}
func integrationRuntime(provider Provider) *runtimeconfig.Store {
if value, ok := provider.(integrationRuntimeProvider); ok {
return value.IntegrationRuntime()
if provider != nil {
return provider.IntegrationRuntime()
}
return nil
}
+3
View File
@@ -127,6 +127,9 @@ func taskLogFromPO(v taskLogPO) *taskbiz.TimedTaskLog {
return &taskbiz.TimedTaskLog{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, TaskID: v.TaskID, TaskName: v.TaskName, TriggerType: v.TriggerType, StartedAt: v.StartedAt, FinishedAt: v.FinishedAt, DurationMS: v.DurationMS, Status: v.Status, ErrorMsg: v.ErrorMsg, Output: v.Output}
}
func (r *taskRepo) ListTaskLogs(ctx context.Context, page, size int, taskID uint, status string) ([]*taskbiz.TimedTaskLog, int64, error) {
if !r.data.DatabaseReady() {
return []*taskbiz.TimedTaskLog{}, 0, nil
}
db := r.data.DB().WithContext(ctx).Model(&taskLogPO{})
if taskID != 0 {
db = db.Where("task_id = ?", taskID)
+11
View File
@@ -15,3 +15,14 @@ func TestTaskRepoListIsEmptyBeforeDatabaseInitialization(t *testing.T) {
t.Fatalf("bootstrap tasks = (%d, %d), want empty", total, len(items))
}
}
func TestTaskRepoLogsAreEmptyBeforeDatabaseInitialization(t *testing.T) {
repo := NewTaskRepo(&Data{})
items, total, err := repo.ListTaskLogs(context.Background(), 0, 0, 0, "")
if err != nil {
t.Fatal(err)
}
if total != 0 || len(items) != 0 {
t.Fatalf("bootstrap task logs = (%d, %d), want empty", total, len(items))
}
}