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 }