refactor(cache): Improve cache expiration using LastAccess timestamp

- Update cache expiration check to use LastAccess instead of CreatedAt
- Reset expiration time on each cache item access
- Enhance cache management with more accurate access tracking
This commit is contained in:
wood chen 2025-02-16 14:12:29 +08:00
parent c51d4869ba
commit 5f67325055
2 changed files with 67 additions and 3 deletions

View File

@ -144,15 +144,15 @@ func (cm *CacheManager) Get(key CacheKey, r *http.Request) (*CacheItem, bool, bo
return nil, false, false
}
// 只检查基本的缓存过期
if time.Since(item.CreatedAt) > cm.maxAge {
// 检查是否过期使用LastAccess而不是CreatedAt
if time.Since(item.LastAccess) > cm.maxAge {
cm.items.Delete(key)
os.Remove(item.FilePath)
cm.missCount.Add(1)
return nil, false, false
}
// 更新访问信息
// 更新访问信息(重置过期时间)
item.LastAccess = time.Now()
atomic.AddInt64(&item.AccessCount, 1)
cm.hitCount.Add(1)

64
internal/cache/manager_test.go vendored Normal file
View File

@ -0,0 +1,64 @@
package cache
import (
"net/http"
"os"
"testing"
"time"
)
func TestCacheExpiry(t *testing.T) {
// 创建临时目录用于测试
tempDir, err := os.MkdirTemp("", "cache-test-*")
if err != nil {
t.Fatal("Failed to create temp dir:", err)
}
defer os.RemoveAll(tempDir)
// 创建缓存管理器设置较短的过期时间5秒用于测试
cm, err := NewCacheManager(tempDir)
if err != nil {
t.Fatal("Failed to create cache manager:", err)
}
cm.maxAge = 5 * time.Second
// 创建测试请求和响应
req, _ := http.NewRequest("GET", "http://example.com/test", nil)
resp := &http.Response{
StatusCode: http.StatusOK,
Header: make(http.Header),
}
testData := []byte("test data")
// 生成缓存键
key := cm.GenerateCacheKey(req)
// 1. 首先放入缓存
_, err = cm.Put(key, resp, testData)
if err != nil {
t.Fatal("Failed to put item in cache:", err)
}
// 2. 立即获取,应该能命中
if _, hit, _ := cm.Get(key, req); !hit {
t.Error("Cache should hit immediately after putting")
}
// 3. 等待3秒未过期再次访问
time.Sleep(3 * time.Second)
if _, hit, _ := cm.Get(key, req); !hit {
t.Error("Cache should hit after 3 seconds")
}
// 4. 再等待3秒总共6秒但因为上次访问重置了时间所以应该还在有效期内
time.Sleep(3 * time.Second)
if _, hit, _ := cm.Get(key, req); !hit {
t.Error("Cache should hit after 6 seconds because last access reset the timer")
}
// 5. 等待6秒超过过期时间且无访问这次应该过期
time.Sleep(6 * time.Second)
if _, hit, _ := cm.Get(key, req); hit {
t.Error("Cache should expire after 6 seconds of no access")
}
}