diff --git a/cache/waf_cache.go b/cache/waf_cache.go new file mode 100644 index 0000000..636221e --- /dev/null +++ b/cache/waf_cache.go @@ -0,0 +1,98 @@ +package cache + +import ( + "errors" + "sync" + "time" +) + +type WafCache struct { + cache map[string]WafCacheItem + mu sync.Mutex +} +type WafCacheItem struct { + value interface{} + createTime time.Time + lastTime time.Time + ttl time.Duration +} + +func InitWafCache() *WafCache { + wafcache := &WafCache{ + cache: make(map[string]WafCacheItem), + mu: sync.Mutex{}, + } + go wafcache.ClearExpirationCacheRoutine() + return wafcache +} +func (wafCache *WafCache) Set(key string, value interface{}) { + wafCache.SetWithTTl(key, value, -1) +} + +func (wafCache *WafCache) SetWithTTl(key string, value interface{}, ttl time.Duration) { + wafCache.mu.Lock() + defer wafCache.mu.Unlock() + createTime := time.Now() + item, found := wafCache.cache[key] + + if found { + createTime = item.createTime + } + wafCache.cache[key] = WafCacheItem{ + value: value, + createTime: createTime, + lastTime: time.Now(), + ttl: ttl, + } +} +func (wafCache *WafCache) GetString(key string) (string, error) { + key1Value := wafCache.Get(key) + if str, ok := key1Value.(string); ok { + return str, nil + } + return "", errors.New("数据不存在") +} +func (wafCache *WafCache) Get(key string) interface{} { + wafCache.mu.Lock() + defer wafCache.mu.Unlock() + item, found := wafCache.cache[key] + if !found { + return nil + } + if time.Since(item.createTime) <= item.ttl { + return item.value + } + delete(wafCache.cache, key) + return nil +} +func (wafCache *WafCache) GetLastTime(key string) (time.Time, error) { + wafCache.mu.Lock() + defer wafCache.mu.Unlock() + item, found := wafCache.cache[key] + if !found { + return time.Time{}, errors.New("数据不存在") + } + if time.Since(item.createTime) <= item.ttl { + return item.lastTime, nil + } + delete(wafCache.cache, key) + return time.Time{}, errors.New("数据已过期") +} +func (wafCache *WafCache) ClearExpirationCache() { + println("准备检测过期键") + now := time.Now() + for key, item := range wafCache.cache { + if now.Sub(item.createTime) > item.ttl { + println("删除" + key) + delete(wafCache.cache, key) + } + } +} +func (wafCache *WafCache) ClearExpirationCacheRoutine() { + println("启动协程检测过期的") + ticker := time.NewTicker(60 * time.Second) + defer ticker.Stop() + for range ticker.C { + wafCache.ClearExpirationCache() + } +} diff --git a/cache/waf_cache_test.go b/cache/waf_cache_test.go new file mode 100644 index 0000000..b9f4ec7 --- /dev/null +++ b/cache/waf_cache_test.go @@ -0,0 +1,35 @@ +package cache + +import ( + "testing" + "time" +) + +func TestWafCache_SetWithTTl(t *testing.T) { + wafcache := InitWafCache() + wafcache.SetWithTTl("KEY1", "我是key1的值", 5*time.Second) + time.Sleep(65 * time.Second) + key1Value := wafcache.Get("KEY1") + if str, ok := key1Value.(string); ok { + println(str) + } + time.Sleep(65 * time.Second) + +} +func TestWafCache_GetLastTime(t *testing.T) { + wafcache := InitWafCache() + wafcache.SetWithTTl("KEY1", "我是key1的值", 5*time.Second) + key1Value, err := wafcache.GetLastTime("KEY1") + if err == nil { + println(key1Value.String()) + } +} + +func TestWafCache_GetString(t *testing.T) { + wafcache := InitWafCache() + wafcache.SetWithTTl("KEY1", "我是key1的值字符串", 5*time.Second) + key1Value, err := wafcache.GetString("KEY1") + if err == nil { + println(key1Value) + } +}