优化结构
This commit is contained in:
@@ -77,93 +77,6 @@ func (r *ResourceRegistry) Replace(resources Resources) {
|
||||
r.mu.Unlock()
|
||||
}
|
||||
|
||||
func (r *ResourceRegistry) Logger() *slog.Logger { return r.Snapshot().Logger }
|
||||
|
||||
func (r *ResourceRegistry) SetLogger(logger *slog.Logger) {
|
||||
r.update(func(resources *Resources) { resources.Logger = logger })
|
||||
}
|
||||
|
||||
func (r *ResourceRegistry) DB() *gorm.DB { return r.Snapshot().DB }
|
||||
|
||||
func (r *ResourceRegistry) SetDB(db *gorm.DB) {
|
||||
r.update(func(resources *Resources) { resources.DB = db })
|
||||
}
|
||||
|
||||
// NamedDB returns a configured secondary database by alias. An empty alias
|
||||
// resolves to the primary database.
|
||||
func (r *ResourceRegistry) NamedDB(name string) *gorm.DB {
|
||||
if name == "" {
|
||||
return r.DB()
|
||||
}
|
||||
return r.Snapshot().NamedDBs[name]
|
||||
}
|
||||
|
||||
// SetNamedDBs replaces the complete secondary-database alias set.
|
||||
func (r *ResourceRegistry) SetNamedDBs(databases map[string]*gorm.DB) {
|
||||
r.update(func(resources *Resources) { resources.NamedDBs = cloneDBMap(databases) })
|
||||
}
|
||||
|
||||
func (r *ResourceRegistry) Redis() redis.UniversalClient { return r.Snapshot().Redis }
|
||||
|
||||
func (r *ResourceRegistry) SetRedis(client redis.UniversalClient) {
|
||||
r.update(func(resources *Resources) { resources.Redis = client })
|
||||
}
|
||||
|
||||
// NamedRedis returns a configured secondary Redis client by alias. An empty
|
||||
// alias resolves to the primary Redis client.
|
||||
func (r *ResourceRegistry) NamedRedis(name string) redis.UniversalClient {
|
||||
if name == "" {
|
||||
return r.Redis()
|
||||
}
|
||||
return r.Snapshot().NamedRedis[name]
|
||||
}
|
||||
|
||||
// SetNamedRedis replaces the complete secondary-Redis alias set.
|
||||
func (r *ResourceRegistry) SetNamedRedis(clients map[string]redis.UniversalClient) {
|
||||
r.update(func(resources *Resources) { resources.NamedRedis = cloneRedisMap(clients) })
|
||||
}
|
||||
|
||||
func (r *ResourceRegistry) Mongo() *mongo.Client { return r.Snapshot().Mongo }
|
||||
|
||||
func (r *ResourceRegistry) SetMongo(client *mongo.Client) {
|
||||
r.update(func(resources *Resources) { resources.Mongo = client })
|
||||
}
|
||||
|
||||
func (r *ResourceRegistry) Storage() FileStorage { return r.Snapshot().Storage }
|
||||
|
||||
func (r *ResourceRegistry) SetStorage(storage FileStorage) {
|
||||
r.update(func(resources *Resources) { resources.Storage = storage })
|
||||
}
|
||||
|
||||
func (r *ResourceRegistry) MQ() platformmq.Registry { return r.Snapshot().MQ }
|
||||
|
||||
func (r *ResourceRegistry) SetMQ(registry platformmq.Registry) {
|
||||
r.update(func(resources *Resources) { resources.MQ = registry })
|
||||
}
|
||||
|
||||
func (r *ResourceRegistry) WebSocket() platformws.Hub { return r.Snapshot().WebSocket }
|
||||
|
||||
func (r *ResourceRegistry) SetWebSocket(hub platformws.Hub) {
|
||||
r.update(func(resources *Resources) { resources.WebSocket = hub })
|
||||
}
|
||||
|
||||
func (r *ResourceRegistry) Scheduler() Scheduler { return r.Snapshot().Scheduler }
|
||||
|
||||
func (r *ResourceRegistry) SetScheduler(scheduler Scheduler) {
|
||||
r.update(func(resources *Resources) { resources.Scheduler = scheduler })
|
||||
}
|
||||
|
||||
func (r *ResourceRegistry) update(change func(*Resources)) {
|
||||
if r == nil || change == nil {
|
||||
return
|
||||
}
|
||||
r.mu.Lock()
|
||||
resources := cloneResources(r.resources)
|
||||
change(&resources)
|
||||
r.resources = normalizeResources(resources)
|
||||
r.mu.Unlock()
|
||||
}
|
||||
|
||||
func normalizeResources(resources Resources) Resources {
|
||||
if resources.Logger == nil {
|
||||
resources.Logger = slog.Default()
|
||||
@@ -248,45 +161,3 @@ func Install(resources Resources) *ResourceRegistry {
|
||||
func DefaultRegistry() *ResourceRegistry { return defaultResources }
|
||||
|
||||
func ResourceSnapshot() Resources { return defaultResources.Snapshot() }
|
||||
|
||||
func ReplaceResources(resources Resources) { defaultResources.Replace(resources) }
|
||||
|
||||
func Logger() *slog.Logger { return defaultResources.Logger() }
|
||||
|
||||
func SetLogger(logger *slog.Logger) { defaultResources.SetLogger(logger) }
|
||||
|
||||
func DB() *gorm.DB { return defaultResources.DB() }
|
||||
|
||||
func SetDB(db *gorm.DB) { defaultResources.SetDB(db) }
|
||||
|
||||
func NamedDB(name string) *gorm.DB { return defaultResources.NamedDB(name) }
|
||||
|
||||
func SetNamedDBs(databases map[string]*gorm.DB) { defaultResources.SetNamedDBs(databases) }
|
||||
|
||||
func Redis() redis.UniversalClient { return defaultResources.Redis() }
|
||||
|
||||
func SetRedis(client redis.UniversalClient) { defaultResources.SetRedis(client) }
|
||||
|
||||
func NamedRedis(name string) redis.UniversalClient { return defaultResources.NamedRedis(name) }
|
||||
|
||||
func SetNamedRedis(clients map[string]redis.UniversalClient) { defaultResources.SetNamedRedis(clients) }
|
||||
|
||||
func Mongo() *mongo.Client { return defaultResources.Mongo() }
|
||||
|
||||
func SetMongo(client *mongo.Client) { defaultResources.SetMongo(client) }
|
||||
|
||||
func Storage() FileStorage { return defaultResources.Storage() }
|
||||
|
||||
func SetStorage(storage FileStorage) { defaultResources.SetStorage(storage) }
|
||||
|
||||
func MQ() platformmq.Registry { return defaultResources.MQ() }
|
||||
|
||||
func SetMQ(registry platformmq.Registry) { defaultResources.SetMQ(registry) }
|
||||
|
||||
func WebSocket() platformws.Hub { return defaultResources.WebSocket() }
|
||||
|
||||
func SetWebSocket(hub platformws.Hub) { defaultResources.SetWebSocket(hub) }
|
||||
|
||||
func TaskScheduler() Scheduler { return defaultResources.Scheduler() }
|
||||
|
||||
func SetTaskScheduler(scheduler Scheduler) { defaultResources.SetScheduler(scheduler) }
|
||||
|
||||
@@ -55,16 +55,16 @@ func (*webSocketStub) OnDisconnect(func(*platformws.Session)) {}
|
||||
|
||||
func TestResourceRegistryDefaults(t *testing.T) {
|
||||
registry := NewResourceRegistry()
|
||||
if registry.Logger() == nil {
|
||||
resources := registry.Snapshot()
|
||||
if resources.Logger == nil {
|
||||
t.Fatal("default logger is nil")
|
||||
}
|
||||
resources := registry.Snapshot()
|
||||
if resources.DB != nil || len(resources.NamedDBs) != 0 || resources.Redis != nil || len(resources.NamedRedis) != 0 || resources.Mongo != nil || resources.Storage != nil || resources.MQ != nil || resources.WebSocket != nil || resources.Scheduler != nil {
|
||||
t.Fatalf("unexpected initialized resource: %#v", resources)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourceRegistryReplaceAndSetters(t *testing.T) {
|
||||
func TestResourceRegistryReplaceAndSnapshot(t *testing.T) {
|
||||
logger := slog.Default().With("test", true)
|
||||
db := &gorm.DB{}
|
||||
redisClient := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"})
|
||||
@@ -76,41 +76,33 @@ func TestResourceRegistryReplaceAndSetters(t *testing.T) {
|
||||
scheduler := &schedulerStub{}
|
||||
|
||||
registry := NewResourceRegistry()
|
||||
inputDBs := map[string]*gorm.DB{"reporting": db}
|
||||
inputRedis := map[string]redis.UniversalClient{"cache": redisClient}
|
||||
registry.Replace(Resources{
|
||||
Logger: logger, DB: db, NamedDBs: map[string]*gorm.DB{"reporting": db},
|
||||
Redis: redisClient, NamedRedis: map[string]redis.UniversalClient{"cache": redisClient}, Mongo: mongoClient,
|
||||
Logger: logger, DB: db, NamedDBs: inputDBs,
|
||||
Redis: redisClient, NamedRedis: inputRedis, Mongo: mongoClient,
|
||||
Storage: storage, MQ: mq, WebSocket: webSocket, Scheduler: scheduler,
|
||||
})
|
||||
resources := registry.Snapshot()
|
||||
if resources.Logger != logger || resources.DB != db || resources.Redis != redisClient || resources.Mongo != mongoClient || resources.Storage != storage || resources.MQ != mq || resources.WebSocket != webSocket || resources.Scheduler != scheduler {
|
||||
t.Fatalf("replacement snapshot does not match: %#v", resources)
|
||||
}
|
||||
if resources.NamedDBs["reporting"] != db || resources.NamedRedis["cache"] != redisClient {
|
||||
t.Fatal("named resource lookup returned the wrong resource")
|
||||
}
|
||||
|
||||
nextDB := &gorm.DB{}
|
||||
registry.SetDB(nextDB)
|
||||
if registry.DB() != nextDB {
|
||||
t.Fatal("database setter did not publish the new database")
|
||||
}
|
||||
if registry.Redis() != redisClient || registry.Storage() != storage {
|
||||
t.Fatal("database setter changed unrelated resources")
|
||||
}
|
||||
if registry.NamedDB("reporting") != db || registry.NamedDB("") != nextDB {
|
||||
t.Fatal("named database lookup returned the wrong resource")
|
||||
}
|
||||
if registry.NamedRedis("cache") != redisClient || registry.NamedRedis("") != redisClient {
|
||||
t.Fatal("named redis lookup returned the wrong resource")
|
||||
}
|
||||
inputDBs := map[string]*gorm.DB{"analytics": db}
|
||||
registry.SetNamedDBs(inputDBs)
|
||||
inputDBs["mutated"] = nextDB
|
||||
if registry.NamedDB("mutated") != nil || registry.NamedDB("analytics") != db {
|
||||
t.Fatal("named database map was not copied")
|
||||
}
|
||||
inputRedis := map[string]redis.UniversalClient{"sessions": redisClient}
|
||||
registry.SetNamedRedis(inputRedis)
|
||||
inputDBs["mutated"] = &gorm.DB{}
|
||||
inputRedis["mutated"] = redisClient
|
||||
if registry.NamedRedis("mutated") != nil || registry.NamedRedis("sessions") != redisClient {
|
||||
t.Fatal("named redis map was not copied")
|
||||
if _, exists := registry.Snapshot().NamedDBs["mutated"]; exists {
|
||||
t.Fatal("named database map was not copied on replacement")
|
||||
}
|
||||
if _, exists := registry.Snapshot().NamedRedis["mutated"]; exists {
|
||||
t.Fatal("named redis map was not copied on replacement")
|
||||
}
|
||||
|
||||
resources.NamedDBs["mutated"] = db
|
||||
if _, exists := registry.Snapshot().NamedDBs["mutated"]; exists {
|
||||
t.Fatal("snapshot shares its named database map with the registry")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,14 +132,16 @@ func TestResourceRegistryConcurrentAccess(t *testing.T) {
|
||||
go func() {
|
||||
defer wait.Done()
|
||||
for step := 0; step < iterations; step++ {
|
||||
registry.SetDB(&gorm.DB{})
|
||||
_ = registry.Snapshot()
|
||||
_ = registry.Logger()
|
||||
registry.Replace(Resources{DB: &gorm.DB{}})
|
||||
if registry.Snapshot().Logger == nil {
|
||||
t.Error("concurrent snapshot lost the default logger")
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
wait.Wait()
|
||||
if registry.DB() == nil {
|
||||
t.Fatal("concurrent setters lost the database")
|
||||
if registry.Snapshot().DB == nil {
|
||||
t.Fatal("concurrent replacement lost the database")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user