|
|
|
package cacheSer
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"gitea.anxinyun.cn/container/common_models"
|
|
|
|
"gitea.anxinyun.cn/container/common_models/constant/redisKey"
|
|
|
|
"gitea.anxinyun.cn/container/common_utils"
|
|
|
|
"log"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
var once sync.Once
|
|
|
|
var cacheWindowMaps sync.Map
|
|
|
|
|
|
|
|
type CacheServer struct {
|
|
|
|
CacheWindowMaps *sync.Map
|
|
|
|
configHelper *common_utils.ConfigHelper
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewCacheServer(configHelper *common_utils.ConfigHelper) *CacheServer {
|
|
|
|
once.Do(func() {
|
|
|
|
cacheWindowMaps = sync.Map{}
|
|
|
|
})
|
|
|
|
return &CacheServer{
|
|
|
|
CacheWindowMaps: &cacheWindowMaps,
|
|
|
|
configHelper: configHelper,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *CacheServer) CreatFilterWindow(stationId int, itemName string, reason string) common_models.CacheWindow {
|
|
|
|
//新测点滑窗 size默认1
|
|
|
|
k := fmt.Sprintf("%d-%s", stationId, itemName)
|
|
|
|
cacheWindow := common_models.NewCacheWindow(k, 1, 0, common_models.FilterParams{}, reason)
|
|
|
|
Filter, err := c.configHelper.GetFilter(stationId)
|
|
|
|
if err == nil {
|
|
|
|
for _, item := range Filter.Items {
|
|
|
|
if itemName == item.FieldName {
|
|
|
|
cacheWindow = common_models.NewCacheWindow(k, item.WindowSize, item.MethodId, item.Params, reason)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cacheWindow
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *CacheServer) UpdateCacheMap(key string, value common_models.CacheWindow) {
|
|
|
|
c.CacheWindowMaps.Store(key, value)
|
|
|
|
if value.Len() == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
err := c.configHelper.SetChainedCacheObjWithExpiration(key, value.ToSaveCache(), time.Hour*6)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("updateCacheMap 异常,err=%s", err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
func (c *CacheServer) DeleteCacheMap(key string, value common_models.CacheWindow) {
|
|
|
|
c.CacheWindowMaps.Delete(key)
|
|
|
|
err := c.configHelper.DeleteChainedCacheObj(key)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("deleteCacheMap 异常,err=%s", err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *CacheServer) readCache(stationId int, itemName string) (common_models.CacheWindow, bool) {
|
|
|
|
key := fmt.Sprintf("%s:%d:%s", redisKey.CacheWindow, stationId, itemName)
|
|
|
|
if obj, ok := c.CacheWindowMaps.Load(key); ok {
|
|
|
|
win, ok2 := obj.(common_models.CacheWindow)
|
|
|
|
return win, ok2
|
|
|
|
}
|
|
|
|
|
|
|
|
Filter, err := c.configHelper.GetFilter(stationId)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("GetFilter 异常,err=%s", err.Error())
|
|
|
|
return common_models.CacheWindow{}, false
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(Filter.Items) == 0 {
|
|
|
|
return common_models.CacheWindow{}, false
|
|
|
|
}
|
|
|
|
for _, item := range Filter.Items {
|
|
|
|
if itemName == item.FieldName {
|
|
|
|
//首次创建,尝试读取缓存
|
|
|
|
if preWindow, err := c.configHelper.GetCacheWindowObj(key); err == nil {
|
|
|
|
log.Printf("CacheWindow读取[%s]", key)
|
|
|
|
return preWindow, true
|
|
|
|
}
|
|
|
|
log.Printf("创建[%s]", key)
|
|
|
|
newWin := c.CreatFilterWindow(stationId, itemName, "default")
|
|
|
|
return newWin, true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return common_models.CacheWindow{}, false
|
|
|
|
}
|
|
|
|
func (c *CacheServer) ReadCacheNew(stationId int, itemName string) (common_models.CacheWindow, bool) {
|
|
|
|
key := fmt.Sprintf("%s:%d:%s", redisKey.CacheWindow, stationId, itemName)
|
|
|
|
win, ok := c.readCache(stationId, itemName)
|
|
|
|
if !ok {
|
|
|
|
log.Printf("无滑窗[%s]", key)
|
|
|
|
return win, ok
|
|
|
|
}
|
|
|
|
|
|
|
|
if win.CheckExpiration() {
|
|
|
|
//过期判定 有没有删除
|
|
|
|
filterItem, err := c.configHelper.GetFilterItem(stationId, itemName)
|
|
|
|
log.Printf("滑窗[%s]过期,err=%v", key, err)
|
|
|
|
if err != nil || filterItem.WindowSize == 0 {
|
|
|
|
log.Printf("滑窗[%s]过期,且FilterItem无配置或窗口长度为0", key)
|
|
|
|
return win, false
|
|
|
|
}
|
|
|
|
//重新创建滑窗
|
|
|
|
preData := win.DeQueueAll()
|
|
|
|
reloadWindow := c.CreatFilterWindow(stationId, itemName, "default")
|
|
|
|
if len(preData) > 0 {
|
|
|
|
for _, datum := range preData {
|
|
|
|
reloadWindow.EnQueue(datum)
|
|
|
|
}
|
|
|
|
log.Printf("滑窗过期,触发重建[%s]", key)
|
|
|
|
return reloadWindow, true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return win, ok
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取缓存总数 测试用
|
|
|
|
func getSizeByCacheWindowMaps() int {
|
|
|
|
size := 0
|
|
|
|
cacheWindowMaps.Range(func(key, value any) bool {
|
|
|
|
size += 1
|
|
|
|
log.Printf("================ CacheWindowMap-key:%v", key)
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
log.Printf("================= CacheWindowMap-size:%v", size)
|
|
|
|
return size
|
|
|
|
}
|