2021-11-30 17:50:21 +08:00
|
|
|
// Package manager...
|
|
|
|
//
|
|
|
|
// Description : 内存的数据存储
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 2021-08-10 9:47 下午
|
|
|
|
package manager
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"git.zhangdeman.cn/zhangdeman/center-config/define/model"
|
2023-12-23 15:46:50 +08:00
|
|
|
"git.zhangdeman.cn/zhangdeman/easylock"
|
|
|
|
"git.zhangdeman.cn/zhangdeman/easymap"
|
2021-11-30 17:50:21 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type storage struct {
|
|
|
|
// 数据锁
|
|
|
|
lock easylock.EasyLock
|
|
|
|
// 命名空间表, 唯一标识 namespace 做key
|
|
|
|
namespaceTable easymap.EasyMap
|
|
|
|
// 命名空间表, 主键 ID 做key
|
|
|
|
namespaceIDTable easymap.EasyMap
|
|
|
|
// 主键 ID 和命名空间的映射关系
|
|
|
|
namespaceIDToNameTable easymap.EasyMap
|
|
|
|
// 命名空间下有哪些配置项
|
|
|
|
namespaceConfigKeyTable easymap.EasyMap
|
|
|
|
// 全局的配置项
|
|
|
|
configTable easymap.EasyMap
|
|
|
|
}
|
|
|
|
|
|
|
|
// InitNamespace 预加载命名空间
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 9:48 下午 2021/8/10
|
|
|
|
func (s *storage) InitNamespace() error {
|
|
|
|
var (
|
|
|
|
namespaceList []*model.Namespace
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
if namespaceList, err = Namespace.GetAllNamespaceByStatus(model.NamespaceStatusNormal); nil != err {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// 存入内存
|
|
|
|
for _, item := range namespaceList {
|
|
|
|
s.CreateNamespace(item)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// InitConfig 预加载配置
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 9:49 下午 2021/8/10
|
|
|
|
func (s *storage) InitConfig() error {
|
|
|
|
var (
|
|
|
|
allConfigList []*model.Config
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
if allConfigList, err = Config.GetAllConfig(); nil != err {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// 按照namespace进行分组
|
|
|
|
groupConfig := make(map[int64][]string)
|
|
|
|
|
|
|
|
// 存入内存
|
|
|
|
for _, conf := range allConfigList {
|
|
|
|
if _, exist := groupConfig[conf.NamespaceID]; !exist {
|
|
|
|
groupConfig[conf.NamespaceID] = make([]string, 0)
|
|
|
|
}
|
|
|
|
namespaceName, _ := s.namespaceIDToNameTable.GetString(conf.NamespaceID)
|
|
|
|
configKey := s.CreateConfig(namespaceName, conf.Field, conf.Value)
|
|
|
|
groupConfig[conf.NamespaceID] = append(groupConfig[conf.NamespaceID], configKey)
|
|
|
|
}
|
|
|
|
// 维护内存中命名空间配置项集合
|
|
|
|
for namespaceID, keyList := range groupConfig {
|
|
|
|
s.namespaceConfigKeyTable.Set(namespaceID, keyList)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// CreateNamespace 创建内存的命名空间
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 12:23 上午 2021/8/11
|
|
|
|
func (s *storage) CreateNamespace(namespaceInfo *model.Namespace) {
|
|
|
|
s.namespaceTable.Set(namespaceInfo.Namespace, namespaceInfo)
|
|
|
|
s.namespaceIDTable.Set(namespaceInfo.ID, namespaceInfo)
|
|
|
|
s.namespaceIDToNameTable.Set(namespaceInfo.ID, namespaceInfo.Namespace)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNamespace 获取命名空间信息
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 2:16 下午 2021/11/30
|
|
|
|
func (s *storage) GetNamespace(np string) (*model.Namespace, error) {
|
|
|
|
var (
|
|
|
|
result interface{}
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
if result, err = s.namespaceTable.Get(np); nil != err {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
v, ok := result.(*model.Namespace)
|
|
|
|
if !ok {
|
|
|
|
return nil, errors.New("namespace info parse error")
|
|
|
|
}
|
|
|
|
return v, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// CreateConfig 创建内存配置(已存在,自动更新)
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 12:48 上午 2021/8/11
|
|
|
|
func (s *storage) CreateConfig(namespaceName string, field string, value string) string {
|
|
|
|
confKey := s.getConfigKey(namespaceName, field)
|
|
|
|
s.configTable.Set(confKey, value)
|
|
|
|
return confKey
|
|
|
|
}
|
|
|
|
|
|
|
|
// DeleteNamespace 删除内存的命名空间
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 12:22 上午 2021/8/11
|
|
|
|
func (s *storage) DeleteNamespace(namespaceName string, namespaceID int64) {
|
|
|
|
s.namespaceTable.Del(namespaceName)
|
|
|
|
s.namespaceIDToNameTable.Del(namespaceID)
|
|
|
|
s.namespaceIDTable.Del(namespaceID)
|
|
|
|
// 查询命名空间的配置
|
|
|
|
var confKeyList []string
|
|
|
|
_ = s.configTable.GetWithReceiver(namespaceID, &confKeyList)
|
|
|
|
// 删除命名空间对应内存配置
|
|
|
|
for _, key := range confKeyList {
|
|
|
|
s.configTable.Del(key)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateConfig 更新内存配置
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 12:29 上午 2021/8/11
|
|
|
|
func (s *storage) UpdateConfig(namespaceInfo *model.Namespace, wg *sync.WaitGroup) {
|
|
|
|
if nil != wg {
|
|
|
|
wg.Done()
|
|
|
|
}
|
|
|
|
// 查询命名空间的配置
|
|
|
|
var (
|
|
|
|
confKeyList []string
|
|
|
|
configList []*model.Config
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
// 当前内存数据表
|
|
|
|
_ = s.namespaceConfigKeyTable.GetWithReceiver(namespaceInfo.ID, &confKeyList)
|
|
|
|
currentMemConfigTable := make(map[string]bool)
|
|
|
|
for _, confKey := range confKeyList {
|
|
|
|
currentMemConfigTable[confKey] = true
|
|
|
|
}
|
|
|
|
if configList, err = Config.GetNamespaceConfig(namespaceInfo.ID); nil != err {
|
|
|
|
// 出了异常, 不处理内存数据
|
|
|
|
return
|
|
|
|
}
|
|
|
|
newConfKeyList := make([]string, 0)
|
|
|
|
for _, item := range configList {
|
|
|
|
confKey := s.CreateConfig(namespaceInfo.Namespace, item.Field, item.Value)
|
|
|
|
newConfKeyList = append(newConfKeyList, confKey)
|
|
|
|
delete(currentMemConfigTable, confKey)
|
|
|
|
}
|
|
|
|
// 执行完 currentMemConfigTable 还有数据, 说明是已被删除数据, 从内存移除
|
|
|
|
for confKey := range currentMemConfigTable {
|
|
|
|
s.configTable.Del(confKey)
|
|
|
|
}
|
|
|
|
// 更新命名空间维护的confKey
|
|
|
|
s.namespaceConfigKeyTable.Set(namespaceInfo.ID, newConfKeyList)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetConf 读取内存配置
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 1:09 上午 2021/8/11
|
|
|
|
func (s *storage) GetConf(namespaceName string, field string) string {
|
|
|
|
confKey := s.getConfigKey(namespaceName, field)
|
|
|
|
// 前置已经保证写入内存的一定是字符串
|
|
|
|
confValue, err := s.configTable.GetString(confKey)
|
|
|
|
if nil != err {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return confValue
|
|
|
|
}
|
|
|
|
|
|
|
|
// TimerUpdate 定时更新
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 12:09 上午 2021/8/11
|
|
|
|
func (s *storage) TimerUpdate(timer int64) {
|
|
|
|
if timer <= 0 {
|
|
|
|
// 默认 10s 更新一次
|
|
|
|
timer = 10
|
|
|
|
}
|
|
|
|
for {
|
|
|
|
time.Sleep(time.Duration(timer) * time.Second)
|
|
|
|
// 计时器到期
|
|
|
|
var (
|
|
|
|
namespaceList []*model.Namespace
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
if namespaceList, err = Namespace.GetAllNamespaceByStatus(model.NamespaceStatusNormal); nil != err {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
namespaceTable := make(map[string]int64)
|
|
|
|
for _, item := range namespaceList {
|
|
|
|
namespaceTable[item.Namespace] = item.ID
|
|
|
|
}
|
|
|
|
// 当前内存数据
|
|
|
|
memData := s.namespaceIDToNameTable.GetAll()
|
|
|
|
for namespaceID, namespaceName := range memData {
|
|
|
|
if _, exist := namespaceTable[fmt.Sprintf("%v", namespaceID)]; !exist {
|
|
|
|
// 更新后不存在, 删除
|
|
|
|
id, _ := namespaceID.(int64)
|
|
|
|
name, _ := namespaceName.(string)
|
|
|
|
s.DeleteNamespace(name, id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
wg := &sync.WaitGroup{}
|
|
|
|
wg.Add(len(namespaceList))
|
|
|
|
for _, namespaceInfo := range namespaceList {
|
|
|
|
go s.UpdateConfig(namespaceInfo, wg)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// getConfigKey 获取内存配置key
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 1:08 上午 2021/8/11
|
|
|
|
func (s *storage) getConfigKey(namespaceName string, field string) string {
|
|
|
|
return fmt.Sprintf("%v_%v", namespaceName, field)
|
|
|
|
}
|