dragonfly/manager/configsvc/configmap.go

142 lines
3.2 KiB
Go

package configsvc
import (
"context"
"sync"
)
type ConfigMap struct {
mu sync.Mutex
store Store
configs map[string]*Config
objects map[string]*Config
}
func NewConfigMap(store Store) *ConfigMap {
return &ConfigMap{
store: store,
configs: make(map[string]*Config),
objects: make(map[string]*Config)}
}
func (cm *ConfigMap) AddConfig(ctx context.Context, id string, config *Config) (*Config, error) {
if config, err := cm.store.AddConfig(ctx, id, config); err != nil {
return nil, err
} else {
cm.loadToCache(ctx, id, config)
return config, nil
}
}
func (cm *ConfigMap) DeleteConfig(ctx context.Context, id string) (*Config, error) {
if config, err := cm.store.DeleteConfig(ctx, id); err != nil {
return nil, err
} else if config != nil {
cm.deleteCache(ctx, id, config)
return config, nil
} else {
return nil, nil
}
}
func (cm *ConfigMap) UpdateConfig(ctx context.Context, id string, config *Config) (*Config, error) {
if config, err := cm.store.UpdateConfig(ctx, id, config); err != nil {
return nil, err
} else {
cm.loadToCache(ctx, id, config)
return config, nil
}
}
func (cm *ConfigMap) GetConfig(ctx context.Context, id string) (*Config, error) {
if config, exist := cm.loadFromCache(ctx, id); exist {
return config, nil
} else {
if config, err := cm.store.GetConfig(ctx, id); err != nil {
return nil, err
} else {
cm.loadToCache(ctx, id, config)
return config, nil
}
}
}
func (cm *ConfigMap) ListConfigs(ctx context.Context, object string) ([]*Config, error) {
if configs, err := cm.store.ListConfigs(ctx, object); err != nil {
return nil, err
} else {
return configs, nil
}
}
func (cm *ConfigMap) LatestConfig(ctx context.Context, object string, objType string) (*Config, error) {
if config, exist := cm.latestFromCache(ctx, object, objType); exist {
return config, nil
} else {
if config, err := cm.store.LatestConfig(ctx, object, objType); err != nil {
return nil, err
} else {
cm.loadToCache(ctx, config.ID, config)
return config, nil
}
}
}
func (cm *ConfigMap) latestFromCache(ctx context.Context, object string, objType string) (*Config, bool) {
cm.mu.Lock()
defer cm.mu.Unlock()
if config, exist := cm.objects[object]; exist {
if config.Type == objType {
return config, true
}
}
return nil, false
}
func (cm *ConfigMap) loadFromCache(ctx context.Context, id string) (*Config, bool) {
cm.mu.Lock()
defer cm.mu.Unlock()
if config, exist := cm.configs[id]; exist {
return config, true
}
return nil, false
}
func (cm *ConfigMap) loadToCache(ctx context.Context, id string, config *Config) {
cm.mu.Lock()
defer cm.mu.Unlock()
if cur, exist := cm.configs[id]; exist {
if cur.Version <= config.Version {
cm.configs[id] = config
}
} else {
cm.configs[id] = config
}
if cur, exist := cm.objects[config.Object]; exist {
if cur.Version <= config.Version {
cm.objects[config.Object] = config
}
} else {
cm.objects[config.Object] = config
}
}
func (cm *ConfigMap) deleteCache(ctx context.Context, id string, config *Config) {
cm.mu.Lock()
defer cm.mu.Unlock()
if _, exist := cm.configs[id]; exist {
delete(cm.configs, id)
}
if _, exist := cm.objects[config.Object]; exist {
delete(cm.objects, config.Object)
}
}