This commit is contained in:
2026-08-16 22:38:44 +08:00
parent 1945d34894
commit 560ae46b82
19 changed files with 345 additions and 112 deletions
+33 -17
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"log/slog"
"sync"
"sync/atomic"
"time"
"github.com/google/wire"
@@ -16,17 +17,18 @@ import (
var ProviderSet = wire.NewSet(NewData, NewRuntimeSettings, NewTokenIssuer, NewUserRepo, NewInitializationRepo, NewAuthorityAccessRepo, NewAPIRepo, NewPermissionRepo, NewMenuRepo, NewDepartmentRepo, NewPositionRepo, NewDictionaryRepo, NewParameterRepo, NewAPITokenRepo, NewSecurityRepo, NewVersionRepo, NewExportRepo, NewAuditRepo, NewAuditRecorderRepo, NewLogFileRepo, NewTaskRepo, NewMediaRepo, NewAnnouncementRepo, NewEmailRepo, NewCache, NewFileStorage)
type Data struct {
initMu sync.Mutex
configMu sync.Mutex
gormDB *reloadableDB
redis *reloadableRedis
mongo *reloadableMongo
runtime *conf.Runtime
storage *reloadableStorage
dbListMu sync.RWMutex
dbList map[string]*gorm.DB
appLogger *slog.Logger
auditLog *dataScopeAuditWriter
initMu sync.Mutex
configMu sync.Mutex
databaseReady atomic.Bool
gormDB *reloadableDB
redis *reloadableRedis
mongo *reloadableMongo
runtime *conf.Runtime
storage *reloadableStorage
dbListMu sync.RWMutex
dbList map[string]*gorm.DB
appLogger *slog.Logger
auditLog *dataScopeAuditWriter
}
func (d *Data) logger() *slog.Logger {
@@ -90,22 +92,35 @@ func NewData(runtime *conf.Runtime, appLogger *slog.Logger) (*Data, func(), erro
appLogger = slog.Default()
}
c := runtime.Data()
if c == nil || c.Database == nil {
return nil, nil, fmt.Errorf("database configuration is required")
if c == nil {
c = &conf.Data{}
}
if c.Database == nil {
// An empty database block is the Kratos equivalent of GVA's empty
// Dbname: the service starts on the bootstrap database so /init/checkdb
// and /init/initdb remain available.
c.Database = &conf.Data_Database{}
}
d := &Data{runtime: runtime, appLogger: appLogger}
db, err := openDatabase(c.Database, false, "", appLogger)
usingFallback := false
if err != nil {
usingFallback := !databaseConnectionConfigured(c.Database)
var db *gorm.DB
var err error
if !usingFallback {
db, err = openDatabase(c.Database, false, "", appLogger)
}
if usingFallback || err != nil {
// The initialization endpoint must remain available when the configured
// target database has not been created yet.
appLogger.Warn("configured database unavailable before initialization", "mod", "system", "error", err)
if err != nil {
appLogger.Warn("configured database unavailable before initialization", "mod", "system", "error", err)
}
db, err = openFallbackDatabase(appLogger)
if err != nil {
return nil, nil, fmt.Errorf("open bootstrap database: %w", err)
}
usingFallback = true
}
d.databaseReady.Store(!usingFallback)
d.gormDB = newReloadableDB(db, d.enqueueDataScopeAudit)
d.auditLog = newDataScopeAuditWriter(d, appLogger)
d.dbList, err = openDatabaseList(c.DatabaseList, appLogger)
@@ -183,4 +198,5 @@ func openRedis(config *conf.Data_Redis, enabled bool, appLogger ...*slog.Logger)
func (d *Data) activateDatabase(db *gorm.DB, config *conf.Data_Database) {
d.gormDB.replace(db, d.enqueueDataScopeAudit)
d.runtime.UpdateDatabase(config)
d.databaseReady.Store(true)
}